Wie kann ich Dateien in einem Linux-Verzeichnis rekursiv zählen?
Ich habe dies gefunden:
find DIR_NAME -type f ¦ wc -l
Wenn ich dies jedoch ausführe, wird folgende Fehlermeldung angezeigt.
find: Pfade müssen vor dem Ausdruck stehen: ¦
Wie kann ich Dateien in einem Linux-Verzeichnis rekursiv zählen?
Ich habe dies gefunden:
find DIR_NAME -type f ¦ wc -l
Wenn ich dies jedoch ausführe, wird folgende Fehlermeldung angezeigt.
find: Pfade müssen vor dem Ausdruck stehen: ¦
Wenn Sie Fehlerfälle vermeiden wollen, erlauben Sie nicht wc -l
um Dateien mit Zeilenumbrüchen zu sehen (diese werden als 2+ Dateien gezählt)
Betrachten wir z. B. den Fall, dass wir eine einzelne Datei mit einem einzigen EOL-Zeichen darin haben
> mkdir emptydir && cd emptydir
> touch $'file with EOL(\n) character in it'
> find -type f
./file with EOL(?) character in it
> find -type f | wc -l
2
Zumindest seit gnu wc
scheint keine Option zum Lesen/Zählen einer Liste mit Null-Terminierung (außer aus einer Datei) zu haben. Die einfachste Lösung wäre, keine Dateinamen zu übergeben, sondern jedes Mal eine statische Ausgabe, wenn eine Datei gefunden wird, z.B. im gleichen Verzeichnis wie oben
> find -type f -exec printf '\n' \; | wc -l
1
Oder wenn Ihr find
unterstützt es
> find -type f -printf '\n' | wc -l
1
Um festzustellen, wie viele Dateien sich im aktuellen Verzeichnis befinden, geben Sie ein ls -1 | wc -l
. Dies verwendet wc
um die Anzahl der Zeilen zu zählen (-l)
in der Ausgabe von ls -1
. Dotfiles werden nicht mitgezählt. Bitte beachten Sie, dass ls -l
(das ist ein "L" statt einer "1" wie in den vorherigen Beispielen), die ich in früheren Versionen dieses HOWTOs verwendet habe, gibt die Anzahl der Dateien um eins höher an als die tatsächliche Anzahl. Vielen Dank an Kam Nejad für diesen Hinweis.
Wenn Sie nur Dateien zählen und symbolische Links NICHT einbeziehen wollen (nur ein Beispiel dafür, was Sie sonst noch tun könnten), könnten Sie verwenden ls -l | grep -v ^l | wc -l
(diesmal ist es ein "L" und keine "1", wir wollen hier eine "lange" Auflistung). grep
prüft, ob eine Zeile mit "l" beginnt (was auf einen Link hinweist), und verwirft diese Zeile (-v).
Relative Geschwindigkeit: "ls -1 /usr/bin/ | wc -l" dauert etwa 1,03 Sekunden auf einem unbelasteten 486SX25 (/usr/bin/ hat auf diesem Rechner 355 Dateien). " ls -l /usr/bin/ | grep -v ^l | wc -l
" dauert etwa 1,19 Sekunden.
Source : http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x700.html
Für Verzeichnisse mit Leerzeichen im Namen ... (basierend auf verschiedenen Antworten oben) -- rekursiv den Verzeichnisnamen mit der Anzahl der Dateien darin ausgeben:
find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done
Beispiel (zur besseren Lesbarkeit formatiert):
pwd
/mnt/Vancouver/Programming/scripts/claws/corpus
ls -l
total 8
drwxr-xr-x 2 victoria victoria 4096 Mar 28 15:02 'Catabolism - Autophagy; Phagosomes; Mitophagy'
drwxr-xr-x 3 victoria victoria 4096 Mar 29 16:04 'Catabolism - Lysosomes'
ls 'Catabolism - Autophagy; Phagosomes; Mitophagy'/ | wc -l
138
## 2 dir (one with 28 files; other with 1 file):
ls 'Catabolism - Lysosomes'/ | wc -l
29
Die Verzeichnisstruktur lässt sich besser visualisieren mit tree
:
tree -L 3 -F .
.
Catabolism - Autophagy; Phagosomes; Mitophagy/
1
10
[ ... SNIP! (138 files, total) ... ]
98
99
Catabolism - Lysosomes/
1
10
[ ... SNIP! (28 files, total) ... ]
8
9
aaa/
bbb
3 directories, 167 files
man find | grep mindep
-mindepth levels
Do not apply any tests or actions at levels less than levels
(a non-negative integer). -mindepth 1 means process all files
except the starting-points.
ls -p | grep -v /
(unten verwendet) stammt aus Antwort 2 unter https://unix.stackexchange.com/questions/48492/list-only-regular-files-but-not-directories-in-current-directory
find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done
./Catabolism - Autophagy; Phagosomes; Mitophagy: 138
./Catabolism - Lysosomes: 28
./Catabolism - Lysosomes/aaa: 1
Anwendung: Ich möchte die maximale Anzahl von Dateien unter mehreren hundert Verzeichnissen (alle Tiefe = 1) finden [Ausgabe unten wieder für Lesbarkeit formatiert]:
date; pwd
Fri Mar 29 20:08:08 PDT 2019
/home/victoria/Mail/2_RESEARCH - NEWS
time find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done > ../../aaa
0:00.03
[victoria@victoria 2_RESEARCH - NEWS]$ head -n5 ../../aaa
./RNA - Exosomes: 26
./Cellular Signaling - Receptors: 213
./Catabolism - Autophagy; Phagosomes; Mitophagy: 138
./Stress - Physiological, Cellular - General: 261
./Ancient DNA; Ancient Protein: 34
[victoria@victoria 2_RESEARCH - NEWS]$ sed -r 's/(^.*): ([0-9]{1,8}$)/\2: \1/g' ../../aaa | sort -V | (head; echo ''; tail)
0: ./Genomics - Gene Drive
1: ./Causality; Causal Relationships
1: ./Cloning
1: ./GenMAPP 2
1: ./Pathway Interaction Database
1: ./Wasps
2: ./Cellular Signaling - Ras-MAPK Pathway
2: ./Cell Death - Ferroptosis
2: ./Diet - Apples
2: ./Environment - Waste Management
988: ./Genomics - PPM (Personalized & Precision Medicine)
1113: ./Microbes - Pathogens, Parasites
1418: ./Health - Female
1420: ./Immunity, Inflammation - General
1522: ./Science, Research - Miscellaneous
1797: ./Genomics
1910: ./Neuroscience, Neurobiology
2740: ./Genomics - Functional
3943: ./Cancer
4375: ./Health - Disease
sort -V
ist eine natürliche Sortierung. ... Meine maximale Anzahl von Dateien in einem dieser (Claws Mail) Verzeichnisse beträgt also 4375 Dateien. Wenn ich mit der linken Maustaste ( https://stackoverflow.com/a/55409116/1904943 ) diese Dateinamen -- sie sind alle numerisch benannt, beginnend mit 1, in jedem Verzeichnis -- und auf 5 Gesamtziffern auffüllen, sollte ich in Ordnung sein.
Nachtrag
Ermittlung der Gesamtzahl der Dateien und Unterverzeichnisse in einem Verzeichnis.
$ date; pwd
Tue 14 May 2019 04:08:31 PM PDT
/home/victoria/Mail/2_RESEARCH - NEWS
$ ls | head; echo; ls | tail
Acoustics
Ageing
Ageing - Calorie (Dietary) Restriction
Ageing - Senescence
Agriculture, Aquaculture, Fisheries
Ancient DNA; Ancient Protein
Anthropology, Archaeology
Ants
Archaeology
ARO-Relevant Literature, News
Transcriptome - CAGE
Transcriptome - FISSEQ
Transcriptome - RNA-seq
Translational Science, Medicine
Transposons
USACEHR-Relevant Literature
Vaccines
Vision, Eyes, Sight
Wasps
Women in Science, Medicine
$ find . -type f | wc -l
70214 ## files
$ find . -type d | wc -l
417 ## subdirectories
Mit Bash:
Erstellen Sie ein Array von Einträgen mit ( ) und ermitteln Sie die Anzahl mit #.
FILES=(./*); echo ${#FILES[@]}
Ok, das zählt die Dateien nicht rekursiv, aber ich wollte zuerst die einfache Option zeigen. Ein üblicher Anwendungsfall könnte die Erstellung von Rollover-Backups einer Datei sein. Dabei wird logfile.1, logfile.2, logfile.3 usw. erstellt.
CNT=(./logfile*); mv logfile logfile.${#CNT[@]}
Rekursive Zählung mit bash 4+ globstar
aktiviert (wie von @tripleee erwähnt)
FILES=(**/*); echo ${#FILES[@]}
Um die Anzahl der Dateien rekursiv zu ermitteln, können wir find immer noch auf die gleiche Weise verwenden.
FILES=(`find . -type f`); echo ${#FILES[@]}
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.