Procurando por um grande número de extensões com find

4

Eu estou olhando para criar uma linha de base de extensões de arquivos e, em seguida, procurar o inverso deles (essencialmente a verificação de novas extensões e, em seguida, relatá-los).

Eu tenho:

base_file='find "/volume1/" -type f | grep -E ".*\.[a-zA-Z0-9]*$" | sed -e 's/.*\(\.[a-zA-Z0-9]*\)$//' | sort | uniq -u'

para criar minha linha de base - a pesquisa inicial dos arquivos no volume.

Para uma pequena quantidade de arquivos, usando

find $dir -type f \( -not -name "foo*" -and -not -name "*bar" \) 

funcionou maravilhosamente. Infelizmente, eu tenho toneladas de arquivos, no entanto. Se eu canalizar cada extensão exclusiva para o comando find , isso não funcionará (compreensivelmente).

de saída:

.acx .adb .aex .agt .ahs .alt .amsorm .ANI .ARTX .ASAX .ASDefs .asmdot .ASMDOT .ASPX .atb .atm .aus .auth .authd .awk .ben .Bin .BIO .bkp .bms .boo .bootstrap .bplist .bridgesupport .bto .btt .CBK .ccp .cd .cdm .cdrom .CFGOLD .cfm .cfp .CFS .cg .cidb .cilk .clk .cmptag .CMValidateMovieDataReferenceService .ColorSyncXPCAgent .common .con .CONFIG .COR .cpi .cpu .crc .crdownload .crmlog .cryptodev .csh .ctd .ctl .cue .cws .d .daeexportpreset .daeimportpreset .DATA .dbg .DBG .dbl .DCD .DCX .debug .defaults .defltools .defmtools .der .desktop .dfont .DGDLL .DGN .DictionaryServiceHelper .dig .django .dla .dlb .dlh .dlk .dLL .dlmp .DLO .DMP .DNP .dps .DriverHelper .DRWDOT .dsd .dtc .DTL .dwd .dwfx .dwG .e .eai .eapol .EDB .edc .edited .ENC .eng .ENV .epub .erl .esi .esm .EVM .EVP .ews .example .exv .fac .fatal .fbk .FBK .fbT .FCL .fe .file .fin .fl .FLL .font .FontDownloadHelper .for .fpk .fre .frT .FW .FXP .gadget .Gadget .gdb .generic .ger .gi .glo .gm .gpx .groovy .group .gsl .gss .gws .GZ .ham .hbs .hd .hidden .hkf .hpdata .hs .htb .HTT .hun .hx .hxd .hxx .HXX .IBM .ICNS .igb .IGS .iHB .imaging .IME .IMG .in .INP .install .Installsettings .int .IPConfiguration .IPMonitor .ITK .ITS .iuf .java .jnilib .job .JPEG .jqx .kd .keychainproxy .keys .kondo .krn .kscript .ksh .lfs .libraries .LID .lisp .liveReg .local .LOCAL .lok .lppi .lsl .lt .ltools .mak .mako .mapping .mappings .mas .masm .matlab .mbr .mch .MDE .mdmp .mdw .me .med .MediaLibraryService .mem .mholders .MIF .MIG .min .mk .mm .mno .mobileconfig .mom .mp .MPE .mpq .MPV .mpx .MPX .msdb .MSDefs .msilog .MSM .MSP .mtools .mup .nasm .netsa .new .nfm .nlog .nor .nsi .ntd .numbers .nut .nv .nvv .NWD .O .oai .oct .Ocx .oft .ogv .older .omo .ooc .openAndSavePanelService .ori .orignal .osf .override .pad .page .partial .pas .patch .pbb .pch .Pdf .PDFFileRefsValidator .pdn .PDR .pexe .pfw .phar .pif .pike .pix .PJT .PJX .PLS .plsql .po .pokki .pot .ppf .ppk .pptm .preferences .PRG .prm .PRN .pro .propdesc .prtdot .PRTDOT .prx .PSDefs .PST .psw .pta .ptb .ptg .python .r .rayhosts .rc .rcd .RCF .rd .RecentPictureService .regcccc .registerassistantservice .RLA .rnd .rpk .RPW .RSC .rst .rupldb .rus .salog .sap .SAP .sbt .sbx .sbxx .SCH .schemas .scm .SCR .sct .SDP .sds .sdu .Search .securityd .SEP .set .setup .Setuplog .SFV .sfx .sgi .sgn .sidb .sidd .sigs .sites .skin .slddrt .smc .SMC .smf .smilebox .SOL .spdc .speechsynthesisd .spn .sqfs .squashfs .srt .srx .ssi .st .ste .stg .styx .swb .swtag .TAR .TDC .tdf .tex .th .tib .time .tips .tmx .tpg .tpm .trace .transformed .trm .TSK .tst .Txt .txz .type .udf .ufm .ult .uninstall .upd .upstart .urf .user .User .UserDictionary .UserProfile .UserScriptService .usr .ux .v .vala .values .var .VAR .vbe .VBR .vcs .vcxproj .vdb .vdf .VERSION .VersionsUIHelper .vhdl .vms .vmsn .vmss .VOL .voucher .vps .vsb .vst .vvv .wax .wbt .Wdf .webp .WIZ .wnt .WPT .ws .wsc .wsdl .WSF .wsp .xap .xht .XLL .xlS .XLT .xmp .xpfwext .xtext .yaml .zipx .zz

Como posso pesquisar todos esses, ou inversamente, sem incorrer em problemas? Ou, mais importante, existe uma solução melhor para esse tipo de tarefa?

    
por sgtsnarky 29.03.2017 / 00:55

2 respostas

2

Você pode usar a opção grep do -f , que permite pesquisar uma lista de padrões armazenados em um arquivo:

# find "$dir" -type f | grep -f ext_patterns.txt

Aqui, o arquivo ext_patterns.txt deve conter extensões como regex, como:

\.html$
\.java$
\.jpg$

Você pode criar esse arquivo da mesma maneira que cria sua linha de base. Aqui está um comando usando awk :

find -type f -name "*.*" \
| awk -F. '{ print "\." $NF "$" }' \
| sort -u \
> ext_patterns.txt

Aqui find nomes de arquivos com uma extensão; awk imprime a extensão junto com um ponto inicial (com escape) e um final $ (código regex significando "fim de linha"); e sort -u torna cada padrão único.

    
por 29.03.2017 / 01:37
0

Supondo que você tenha o GNU find ou FreeBSD / macOS, você pode construir uma expressão regular grande que corresponda a todos os padrões e listar arquivos usando -regex . Tenha em atenção que a construção da expressão regular não é simples: tem de se ocupar de caracteres especiais nas extensões. Seu código atual já não está fazendo nada sensato se a extensão de um nome de arquivo contiver uma nova linha. Com as ferramentas GNU, você pode fazer (não testado)

new_extensions=$(find / -regextype posix-extended -name '*.*' -type f ! -regex "$old_regex" -print0 |
                 sed -z 's/.*\.//; s/[][\$^.()|*+?]/\&/g' |
                 sort -zu | tr '
new_extensions=$(find / -regextype posix-extended -name '*.*' -type f ! -regex "$old_regex" -print0 |
                 sed -z 's/.*\.//; s/[][\$^.()|*+?]/\&/g' |
                 sort -zu | tr '%pre%' '|')
if [ "$new_extensions" = "|" ]; then
  echo "No new extensions"
else
  new_regex="\.(${new_extensions%?})\$"
fi
' '|') if [ "$new_extensions" = "|" ]; then echo "No new extensions" else new_regex="\.(${new_extensions%?})\$" fi

Acho que você ficará melhor com um script perl / python / ruby. Você pode começar com find2perl ou usar os.walk do Python.

    
por 30.03.2017 / 02:11

Tags