Ich möchte einen Verzeichnisbaum rekursiv durchsuchen und die Anzahl der in jedem Ordner verfügbaren Dateien auflisten, deren Name einer bestimmten Zeichenfolge entspricht. Tatsächlich möchte ich Ergebnisse zurückgeben von:
ls -l | wc -l
für jeden Ordner, den ich über find
identifiziert habe .
Code
Der folgende Code listet korrekt die Anzahl der Dateien in jedem Ordner auf, dessen Name Magic Data enthält Zeichenfolge.
find /path/to/cool/stuff
-maxdepth 4
-type d
-name '*Magic Data*'
-print0 | xargs
--verbose
-0 -I {} ls -l {}
Ich möchte es erweitern und Ergebnisse von ls
leiten zu wc -l
.
Versuch
find /path/to/cool/stuff
-maxdepth 4
-type d
-name '*Magic Data*'
-print0 | xargs
--verbose
-0 -I {} ls -l {} | wc -l
Dies schlägt fehl und gibt Folgendes aus:
ls -l /path/to/cool/stuff/some/folders/Magic Data
ls -l /path/to/cool/stuff/some/folders2/Magic Data
Gewünschte Ausgabe
/path/to/cool/stuff/some/folders/Magic Data 29
/path/to/cool/stuff/some/folders2/Magic Data 30
Die gewünschte Ausgabe würde enthalten:
- Vollständiger Pfad zum gesuchten Ordner
- Ausgabe von
wc -l
, was in diesem Fall die Anzahl der nicht versteckten Dateien widerspiegelt
Akzeptierte Antwort:
Es gibt zwei Möglichkeiten, dies zu lösen:
-
Ändern Sie
find
Befehl so, dass er nur die Verzeichnisse eingibt, die Sie interessieren, und dann ein einzelnes Zeichen ausgibt (z. B.x
) für jede darin gefundene Datei. Zählen Sie dann die Anzahl dieses Zeichens, das mitwc -l
erzeugt wird . Es ist sicherer, ein Zeichen als den Pfadnamen auszugeben, da Pfadnamen in Unix potenziell Zeilenumbrüche enthalten können. Diese Lösung ist etwas knifflig, da sie die Verwendung von-prune
beinhaltet um Verzeichnisse zu ignorieren, die uns nicht interessieren, oder alternativ! -path
. -
Suchen Sie die Verzeichnisse so, wie Sie es bisher getan haben, aber verwenden Sie dann ein Inline-Skript, um die darin enthaltenen Dateien zu zählen. Das ist einfacher und was ich unten zeige.
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 {} ';'
Hier finden wir die Verzeichnisse wie Sie, dann führen wir für jedes Verzeichnis diese kurze bash
aus Skript:
dir=$1
set -- "$dir"/*
printf "%s %dn" "$dir" "$#"
Dies übernimmt den Pfadnamen des Verzeichnisses von der Befehlszeile (angegeben durch find
) und erweitert den *
Kugelmuster darin. Durch Setzen des dotglob
Shell-Option auf der Kommandozeile für das Skript, zählen wir garantiert auch versteckte Dateien und Verzeichnisse (remove -O dotglob
um versteckte Namen nicht zu zählen).
Wir machen die Erweiterung aller Namen als Argument zu set
, wodurch die Positionsparameter auf die erweiterten Einträge gesetzt werden. Die Anzahl der Positionsparameter ist als $#
verfügbar , also auch die Anzahl der Dateien in diesem bestimmten Verzeichnis.
Verwandte:
- Die Option -exec von `find` verstehen