Listen Sie die Dateien nach der Anzahl der enthaltenen Zeilen sortiert auf


32

Wie kann ich die Anzahl der Zeilen in den Dateien /group/book/four/wordauflisten, sortiert nach der Anzahl der darin enthaltenen Zeilen?

ls -l Befehl listet sie auf, sortiert sie aber nicht


1
Möchten Sie, dass die Dateien nach Anzahl der Zeilen aufgelistet werden, oder die Anzahl der Zeilen in den Dateien oder beides? ls -lgibt nicht die Anzahl der Zeilen an. ls -lSsortiert Dateien mit einigen lsImplementierungen nach Größe ( Größe entspricht der Anzahl der Bytes im Inhalt).
Stéphane Chazelas

Antworten:


34

Sie sollten einen Befehl wie diesen verwenden:

find /group/book/four/word/ -type f -exec wc -l {} + | sort -rn
  • find: Suche nach Dateien auf dem gewünschten Pfad. Wenn Sie nicht möchten, dass es rekursiv ist, und Ihre findImplementierung dies unterstützt, sollten Sie es -maxdepth 1direkt vor der -execOption hinzufügen .
  • exec: weist den Befehl an, wc -lfür jede Datei ausgeführt zu werden.
  • sort -rn: Sortieren Sie die Ergebnisse in umgekehrter Reihenfolge. Vom Größeren zum Niedrigeren.

(Dies setzt voraus, dass Dateinamen keine Zeilenumbrüche enthalten).


Beachten Sie, dass bei der Übergabe von mehr als einer Datei (oder bei einigen Implementierungen von mehr als einer Datei, die gelesen werden kann) wcauch eine totalZeile gedruckt wird. Daher erhalten Sie hier auch eine oder mehrere "Gesamt" -Zeilen, sofern nicht nur eine Datei vorhanden ist . Sie können an leiten grep /, um sie zu entfernen.
Stéphane Chazelas

upvote wegen sortBefehls
Francisco

Wie kann ich filtern, um nur Dateien mit mindestens X Zeilen anzuzeigen (X = 0 Zeile zum Beispiel ausschließen)?
Matrix

11

Nicht rekursiv

Wahrscheinlich die einfachste Version, wenn Sie keine Rekursivität benötigen:

wc -l /group/book/four/word/*|sort -n

wczählt Zeilen (Option -l) in allen (aber versteckten) ( *) Dateien unter /group/book/four/word/und sortsortiert das Ergebnis (durch die Pipe |) numerisch (Option -n).

Rekursiv

Jemand machte einen Kommentar zu dieser Antwort und erwähnte grep -rlc, bevor er sie unterdrückte. Dies grepist in der Tat eine großartige Alternative, insbesondere wenn Sie Rekursivität benötigen:

grep -rc '^' /group/book/four/word/|tr ':' ' '|sort -n -k2

zählt (Option -c) rekursiv (Option -r) Zeilen, die mit ( grep) '^'( dh Zeilenanfang) im Verzeichnis übereinstimmen /group/book/four/word/. Dann müssen Sie den Doppelpunkt durch ein Leerzeichen ersetzen, z. B. mit tr, um zu helfen sort, die Sie numerisch (Option -n) in der zweiten Spalte (Option -k2) sortieren möchten .

Update: Siehe Stephanes Kommentar über mögliche Einschränkungen und wie Sie diese tatsächlich beseitigen können tr.


3
grep -c .zählt die Zeilen, die mindestens ein gültiges Zeichen enthalten. Mit dieser grep -c '^'Option werden alle Zeilen gezählt (bei einigen grepImplementierungen werden auch nachstehende Zeichen nach der letzten Zeile gezählt ). Beachten Sie, dass nicht alle grepImplementierungen a unterstützen -rund das Verhalten bei diesen Implementierungen unterschiedlich ist. Für brauchen Sie kein :s (Doppelpunkt, kein Semikolon) in Leerzeichen zu übersetzen sort. Verwenden Sie einfach -t:. Beachten Sie, dass davon :ausgegangen wird , dass Dateinamen keine Leerzeichen oder Zeilenumbrüche enthalten .
Stéphane Chazelas

1
Vielen Dank, dass Sie Ihre nicht rekursive Lösung veröffentlicht haben. Ich wusste nicht, wcob man so einen handlichen Gesamtwert hat, wenn man mehrere Pfade passiert. Das Koppeln dieser Funktionalität mit dem Platzhalter und der Pipe zu sortist wirklich sauber.
Qcom

7

Mit zsh:

lines() REPLY=$(wc -l < $REPLY)
printf '%s\n' /group/book/four/word/*(.no+lines)

Wir definieren eine neue Sortierfunktion , dass Antworten mit der Anzahl der Zeilen in der Datei. Und wir verwenden das Glob-Qualifikationsmerkmal, das zusammen mit (für die numerische Sortierung) definiert, wie die Ergebnisse des Glob geordnet werden. ( auch hinzugefügt, um nur reguläre Dateien zu prüfen).lineso+linesn.

Das setzt nicht voraus, welches Zeichen die Dateinamen enthalten dürfen, außer dass versteckte Dateien (die mit beginnen .) weggelassen werden. Fügen Sie das DGlob-Qualifikationsmerkmal hinzu, wenn Sie dies ebenfalls möchten.


2
OP ist markiert mit bashonly ...
l0b0

7
@ l0b0 das bedeutet nicht, dass die nächste Person, die dies benötigt, auch bash ausführt.
Terdon

4

Sie geben nicht an, ob die Dateien auch in Unterverzeichnissen von gespeichert werden sollen /group/book/four/word. Die findLösung in der Antwort von jherran wird in Unterverzeichnisse fallen. Wenn dies nicht gewünscht ist, verwenden Sie stattdessen die Shell:

for file in ./*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Wenn Ihre Dateinamen Zeilenumbrüche enthalten können, können Sie Folgendes verwenden:

for file in ./*; do 
    [ -f "$file" ] && 
        printf "%lu %s\0" "$(wc -l < "$file")" "$file"
done | sort -zn | tr '\0' '\n'

Schließlich, wenn Sie tun wollen in Verzeichnisse absteigen, können Sie dies in verwenden bash4 oder höher:

shopt -s globstar
for file in ./**/*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Beachten Sie, dass Versionen bashvor 4.3 beim rekursiven Absteigen des Verzeichnisbaums (wie zsh's oder tcsh' s ***/*) Symlinks folgten .

Alle oben genannten Lösungen ignorieren auch versteckte Dateien (diejenigen, deren Name mit einem beginnt ., um shopt -s dotglobsie einzuschließen) und enthalten auch die Zeilenanzahl der symbolischen Links (was der findAnsatz nicht tut).


Beachten Sie, dass andere Unterschiede zur Lösung von jherran darin bestehen, dass bei Ihnen auch Symlinks zu regulären Dateien ( -xtype fin GNU find oder *(-.)in zsh) berücksichtigt werden und versteckte Dateien weggelassen werden.
Stéphane Chazelas

@ StéphaneChazelas danke, geklärt. Warum das %luin printf? Wie ich mich erinnere, bedeutet das lange vorzeichenlose Dezimalstellen. Ist das wirklich notwendig? Warum nicht die Zahl als Zeichenfolge behandeln? Macht es einen Unterschied?
Terdon

2
Wenn die wc-Ausgabe leer ist (z. B. weil die Datei nicht lesbar ist), wird diese 0anstelle der leeren Zeichenfolge auf erweitert, was etwas besser ist. Einige Sortierimplementierungen funktionieren mit Ganzzahlen ohne Vorzeichen, andere mit Vorzeichen. %luklingt wie die sicherste Wette, aber es ist wahrscheinlich egal, ob Sie 2^31Linien haben, das wird eh Ewigkeiten dauern.
Stéphane Chazelas

1

Wenn Sie fdeinen wirklich schnellen, in Rust geschriebenen Dateisucher installieren möchten (Sie sollten ihn installieren, es ist trotzdem toll, ihn zu haben)

fd --type=file . | xargs wc -l | sort -n

Grundsätzlich fdlistet xargs die Dateien auf wc, übergibt sie an (steht für word count, wird aber mit -l gezählt) und sortiert sie schließlich von der geringsten Zeilenanzahl bis zur größten Verwendung sort -n.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.