1097 Stimmen

Rekursives Zählen von Dateien in einem Linux-Verzeichnis

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: ¦

13voto

Nestor Urquiza Punkte 2581
tree $DIR_PATH | tail -1

Beispielhafte Ausgabe:

5309 Verzeichnisse, 2122 Dateien

9voto

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

5voto

Sophy Punkte 7895

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

4voto

Victoria Stuart Punkte 3912

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

4voto

nickl- Punkte 7591

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.com

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.

Powered by:

X