Wie listet man die Anzahl der Zeilen jeder Datei in einem Verzeichnis in einem für Menschen lesbaren Format auf?

40

Ich habe eine Liste von Verzeichnissen und Unterverzeichnissen, die große CSV-Dateien enthalten. In diesen Dateien befinden sich ungefähr 500 Millionen Zeilen, jede davon ist ein Rekord. ich würde gerne wissen

  1. Wie viele Zeilen sind in jeder Datei.
  2. Wie viele Zeilen sind im Verzeichnis.
  3. Wie viele Zeilen insgesamt

Am wichtigsten ist, ich brauche dies in "lesbarem Format", z. 12.345.678 statt 12345678

Es wäre schön zu lernen, wie man das auf drei Arten macht. Einfache Vanille-Bash-Tools, awk usw. und Perl (oder Python).

Hexatonisch
quelle

Antworten:

56

Wie viele Zeilen sind in jeder Datei.

Verwenden Sie wcursprünglich für die Wortzählung, glaube ich, aber es kann Zeilen, Wörter, Zeichen, Bytes und die längste Zeilenlänge tun. Die -lOption weist es an, Zeilen zu zählen.

wc -l <filename>

Dies gibt die Anzahl der Zeilen in:

$ wc -l /dir/file.txt
32724 /dir/file.txt

Sie können Daten auch an Folgendes weiterleiten wc:

$ cat /dir/file.txt | wc -l
32724
$ curl google.com --silent | wc -l
63

Wie viele Zeilen sind im Verzeichnis.

Versuchen:

find . -name '*.pl' | xargs wc -l

Ein weiterer Einzeiler:

( find ./ -name '*.pl' -print0 | xargs -0 cat ) | wc -l

Übrigens zählt der wcBefehl neue Zeilencodes, keine Zeilen. Wenn die letzte Zeile in der Datei nicht mit einem neuen Zeilencode endet, wird dies nicht gezählt.

Sie können grep -c ^ verwenden, vollständiges Beispiel:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another shell
done
echo TOTAL LINES COUNTED:  $total

Wie viele Zeilen insgesamt

Ich bin mir nicht sicher, ob ich Ihre Anfrage richtig verstanden habe. Dies gibt beispielsweise Ergebnisse in folgendem Format aus, wobei die Anzahl der Zeilen für jede Datei angezeigt wird:

# wc -l `find /path/to/directory/ -type f`
 103 /dir/a.php
 378 /dir/b/c.xml
 132 /dir/d/e.xml
 613 total

Alternativ kann es sich als nützlich erweisen, nur die Gesamtzahl der Zeichen für neue Zeilen auszugeben, ohne dass die Anzahl der Dateien nach dem folgenden Befehl berechnet wird:

# find /path/to/directory/ -type f -exec wc -l {} \; | awk '{total += $1} END{print total}'
 613

Am wichtigsten ist, ich brauche dies in "lesbarem Format", z. 12.345.678 statt 12345678

Bash hat eine eingebaute printf- Funktion:

printf "%0.2f\n" $T

Wie immer gibt es viele verschiedene Methoden, mit denen die gleichen Ergebnisse erzielt werden können.

malyy
quelle
Übrigens, wie verwende ich printf in Ihren Beispielen? Ich habe versucht, von wc -l darauf zu pfeifen, aber es hat nicht funktioniert.
Hexatonische
versuchen> zu finden. -name '* .pl' | xargs wc -l | awk '{printf ("% 0.2f", $ 1)} {print $ 2}' ändere die Ausgabe von 'printf' für deine Bedürfnisse
malyy
Dies fügt der Zahl jedoch keine Kommas hinzu, um sie besser lesbar zu machen. Am Ende werden nur Nullen hinzugefügt.
Hexatonische
Echo 1000000000000 | xargs printf "% 'd \ n" 1,000,000,000,000
Hexatonic
1
@Hexatonic printfliest seine Argumente nicht von stdin, sondern von der Kommandozeile (Vergleiche Piping mit echound Piping mit cat; catliest von stdin, echonicht). Verwenden Sie stattdessen, printf "$(find ... | xargs ...)"um die Ausgabe als Argumente für bereitzustellen printf.
BallpointBen
13

In vielen Fällen kann es ausreichen , den wcBefehl und den Platzhalter *zu kombinieren .
Wenn sich alle Ihre Dateien in einem einzigen Verzeichnis befinden, können Sie Folgendes aufrufen:

wc -l src/*

Sie können auch mehrere Dateien und Verzeichnisse auflisten:

wc -l file.txt readme src/* include/*

Dieser Befehl zeigt eine Liste der Dateien und die Anzahl der Zeilen.
Die letzte Zeile ist die Summe der Zeilen aller Dateien.


So zählen Sie alle Dateien in einem Verzeichnis rekursiv:

Aktivieren Sie zunächst globstar, indem Sie es shopt -s globstarzu Ihrem .bash_profile hinzufügen. Für die Unterstützung von globstar ist Bash ≥ 4.x erforderlich, das bei Bedarf mit installiert werden brew install bashkann. Sie können Ihre Version mit überprüfen bash --version.

Dann renne:

wc -l **/*

Beachten Sie, dass diese Ausgabe falsch ist, wenn Globstar nicht aktiviert ist.

Thomio
quelle
Und zum rekursiven Zählen von Dateien im aktuellen Verzeichnis:wc -l **/*
Taylor Edmiston
@TaylorEdmiston Für mich (auf Mac) zählt das nur die Dateien genau ein Verzeichnis runter. Es überspringt die Dateien im aktuellen Verzeichnis und warnt bei mehr als einem Verzeichnis, dass es sich um ein Verzeichnis handelt: " wc: parent_dir/child_dir: read: Is a directory"
M. Justin
@Thomio Globstar muss aktiviert sein. Unter macOS ist es meiner Meinung nach standardmäßig deaktiviert. Ich habe gerade eine Änderung an Ihre Antwort gesendet, die den Befehl hinzufügt und erläutert, wie Globstar aktiviert wird.
Taylor Edmiston
2

Dieser Befehl gibt eine Liste von Zeilencodes in jedem Verzeichnis aus:

find . -name '*.*' -type f | xargs wc -l
Suresh.A
quelle
2

Ein bisschen zu spät zum Spiel, aber ich habe eine Reihe von Argumentationsfehlern mit den oben genannten aufgrund der Größe des Verzeichnisses. Das hat bei mir funktioniert:

for i in $(find . -type f); do wc -l $i; done >> /home/counts.txt

Ron Paulfan
quelle
0

catWenn Sie die Dateien zu einer kombinieren und alles nach stdout ausgeben möchten, können Sie dies wc -lfür eine Gesamtanzahl von Zeilen von Dateien in einem Verzeichnis tun :

cat /path/to/directory/* | wc -l
picmate 涅
quelle
0

Ich werde einfach @malyy Antwort für das Folgende erweitern (zu groß für einen Kommentar):

Wie viele Zeilen insgesamt

Viele Antworten verwenden die wcBefehlszeilenoption mit xargs. Das Problem dabei ist, dass xargs auf eine eher kleine plattformabhängige Größe beschränkt ist.

Außerdem gibt es einen Unterschied zwischen BSD (macOS) und GNU (Linux / Homebrew) wc.

Die GNU-Version ist ideal, da sie die Dateiliste anstelle von Argumenten ( --files0) aus einer Datei lesen kann .

Wenn Sie auf einem Mac arbeiten und Homebrew haben, sollten Sie Folgendes tun:

find . -name "*.pl" -print0 | gwc -l --files0=-

Beachten Sie die GWC anstelle von WC .

Adam Gent
quelle