Trova i file in più nomi di cartelle


44

Sto cercando di elencare tutti i file da dir1, dir2, dir3e dir4che potrebbe essere ovunque come una sottodirectory della mia cwdutilizzando il findcomando. Ho provato quanto segue senza successo:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

Ci ho provato anche io posix-extended. Come posso elencare questi file?


trova . -type f -regextype sed -regex ". * / dir [1-4] / [a-z0-9] *" .. risposta più breve finora :) vedi risposta sotto .. unix.stackexchange.com/a/390333 / 242983
alpha_989

Risposte:


59

E se si desidera cercare tre cartelle denominate fooe bar, bazper tutti i *.pyfile, utilizzare questo comando:

find foo bar baz -name "*.py"

quindi se si desidera visualizzare i file dir1 dir2 dir3dall'usofind dir1 dir2 dir3 -type f

prova questo find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;


Avrei dovuto chiarire. Potrei non avere il percorso dei file che desidero cercare. So solo che sono sottodirectory della directory corrente.
Aaron,

usa ./dirinvece didir
harish.venkat il

Il dir dovrebbe comunque essere nel CWD, potrebbe essere inferiore di due livelli (ad esempio ./path/to/dir1), nel qual caso ./dir1non esisterebbe.
Aaron,

ha modificato la risposta.
harish.venkat,

8

È meglio usare la direttiva -path:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

Il che significa: trova tutti i file nella directory corrente dove c'è 'dir1' o 'dir2' o 'dir3' o 'dir4' nel percorso.


Hai la parentesi nel posto sbagliato. Vedi anche -ae -oper l'equivalente standard di GNU -and/ -or.
Stéphane Chazelas,

4

Solo per far sapere a tutti. L'aggiunta .*/prima di ciascuna ha dirrisolto il problema poiché regexsembra corrispondere al percorso completo.


3

Questa è la mia prima idea dopo aver letto le risposte precedenti:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

Ciò tiene conto del fatto che il regex deve corrispondere all'intero nome file ed è più facile da capire.


2

Esempio di ricerca rapida (!) Di file particolari (access_log) in più posizioni definite da caratteri jolly (home directory) e directory generale di log apache2 che applica anche il filtro dei nomi per escludere registri ssl e vecchi registri gzip. Non risponde direttamente alla domanda qui, ma potrebbe essere utile per qualcuno che ha trovato queste istruzioni (come me).

find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

Fai attenzione agli spazi, specialmente vicino a \(e \).

A proposito, l'ho usato per apachetop, per trovare i siti Web più attivi nel mio server.

apachetop -d1 -s9 -p $(find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)

2

non è necessario specificare dir1 in dir4 per nome se si utilizza regextype

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: trova file non directory
  • regextype sed: usa sed regextype
  • regex: cerca usando regex in tutto il percorso
  • ".*/dir[1-4]/[a-z0-9]*":. * all'inizio indica un numero qualsiasi di caratteri che potrebbero essere di tipo (carattere / numero / barra rovesciata (/) ecc.); dir [1-4] significa cercare "dir" seguito da un numero compreso tra 1 e 4; / [^ /] * afferma che seguendo dir1-4 omette qualsiasi percorso che abbia / in essi, quindi restituisce solo i file nella directory dir1-dir4 e ignora tutte le sottodirectory che possono trovarsi all'interno di dir1-dir4.

creato una directory per testarlo: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017


(1) Potremmo non conoscere mai l'esatta situazione o i requisiti di Aaron, ma altre risposte hanno preso la decisione prudente di avere quattro directory, i cui nomi non sono specificati. (Potrebbero essere red, green, bluee yellow, o potrebbero essere John, Paul, Georgee Ringo.) La vostra risposta presuppone che sono letteralmente dir1 , dir2, dir3e dir4. ... (proseguendo)
Scott,

(Proseguendo) ... (2) Perché pensi che Aaron non voglia cercare nelle sottodirectory? Sembra che lo stia dicendo. (3) Perché limitare la ricerca ai file i cui nomi contengono solo lettere minuscole e cifre (escluse le cose come foo_bar, foo.txte FOO)? (4) Perché il tuo testo spiega /[^/]*quando la tua risposta non lo usa?
Scott,

Ciao Scott, questo è per il tuo commento.
alpha_989,

(1-3). menziona "Sto cercando di elencare tutti i file da dir1, dir2, dir3 e dir4 " che potrebbero trovarsi ovunque come sottodirectory del mio cwd , il che significa che dir1-dir4 potrebbe essere ovunque, ma vuole trovare il file giusto all'interno di dir1-dir4. ovviamente, se non è dir1-dir4, devi cambiarlo con i nomi specifici usando red \ | blue \ | green \ | ecc.
alpha_989

4. errore di battitura lì .. ho usato [a-z0-9] * prima che poi mi rendessi conto che [^ /] * è più corto e più inclusivo .. perdete tempo per cambiarlo quando l'ho pubblicato. Grazie per i tuoi commenti attenti.
alpha_989,

0

So che hai specificato che usando find, ma solo per mostrare altre opzioni che puoi usare, puoi usare xargs:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

Puoi avere un file chiamato "cartelle" che contiene qualcosa come:

$ cat folders
dir1
dir2
dir3
dir4

Quindi, puoi fare qualcosa del genere:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

xargs secondo me, mi sento più versatile di trovare -exec. Inoltre puoi fare cose folli come

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.