Vorrei cercare ricorsivamente un albero di directory ed elencare il numero di file disponibili in ciascuna cartella che hanno un nome corrispondente a una determinata stringa. In effetti, vorrei restituire i risultati di:
ls -l | wc -l
per ogni cartella che ho identificato tramite find
.
Codice
Il codice seguente elenca correttamente il numero di file in ciascuna cartella il cui nome contiene Magic Data stringa.
find /path/to/cool/stuff
-maxdepth 4
-type d
-name '*Magic Data*'
-print0 | xargs
--verbose
-0 -I {} ls -l {}
Vorrei espanderlo e reindirizzare i risultati di ls
a wc -l
.
Tentativo
find /path/to/cool/stuff
-maxdepth 4
-type d
-name '*Magic Data*'
-print0 | xargs
--verbose
-0 -I {} ls -l {} | wc -l
Questo non riesce e stampa:
ls -l /path/to/cool/stuff/some/folders/Magic Data
ls -l /path/to/cool/stuff/some/folders2/Magic Data
Potenza desiderata
/path/to/cool/stuff/some/folders/Magic Data 29
/path/to/cool/stuff/some/folders2/Magic Data 30
L'output desiderato conterrebbe:
- Percorso completo della cartella cercata
- Output di
wc -l
, che in questo caso riflette il conteggio dei file non nascosti
Risposta accettata:
Esistono due modi principali per risolvere questo problema:
-
Modifica il
find
comando in modo che inserisca solo le directory che ti interessano e poi stampi un singolo carattere (es.x
) per ogni file trovato all'interno. Quindi conta il numero di quel carattere prodotto conwc -l
. È più sicuro generare un carattere rispetto al nome del percorso poiché i nomi dei percorsi in Unix potrebbero potenzialmente contenere nuove righe. Questa soluzione è un po' complicata in quanto comporta l'utilizzo di-prune
ignorare le directory che non ci interessano, o in alternativa! -path
. -
Trova le directory proprio come hai fatto finora, ma poi usa uno script in linea per eseguire il conteggio dei file all'interno. Questo è più semplice e quello che sto mostrando di seguito.
find /path/to/cool/stuff -maxdepth 4 -type d -name "*Magic Data*'
-exec bash -O dotglob -c '
dir=$1
set -- "$dir"/*
printf "%s %dn" "$dir" "$#"' bash {} ';'
Qui troviamo le directory come fai tu, quindi, per ogni directory, eseguiamo questo breve bash
sceneggiatura:
dir=$1
set -- "$dir"/*
printf "%s %dn" "$dir" "$#"
Questo prende il percorso della directory dalla riga di comando (dato da find
), ed espande il *
pattern glob al suo interno. Impostando il dotglob
opzione shell sulla riga di comando per lo script, abbiamo la garanzia di contare anche i file e le directory nascosti (rimuovere -O dotglob
per non contare i nomi nascosti).
Facciamo l'espansione di tutti i nomi come argomento per set
, che imposterà i parametri posizionali sulle voci espanse. Il numero di parametri posizionali è disponibile come $#
, che è quindi anche il conteggio dei file in quella particolare directory.
Correlati:
- Capire l'opzione -exec di `find`