Zeilen in einer Datei zählen

64

Ich bin sicher, es gibt viele Möglichkeiten, dies zu tun: Wie kann ich die Anzahl der Zeilen in einer Textdatei zählen?

$ <cmd> file.txt
1020 lines
Chris Smith
quelle

Antworten:

98

Die Standardmethode ist mit wc, wobei Argumente verwendet werden, um anzugeben, was gezählt werden soll (Bytes, Zeichen, Wörter usw.). -list für Zeilen:

$ wc -l file.txt
1020 file.txt
Michael Mrozek
quelle
Wie zähle ich die Zeilen in einer Datei, wenn ich Kommentare ignorieren möchte ? Insbesondere möchte ich keine Zeilen zählen, die mit einem Pluszeichen (+), einem Leerzeichen (möglicherweise kein Leerzeichen) und einem Prozentzeichen (%) beginnen. Dies ist die Art und Weise, wie Kommentarzeilen in einem Git Diff einer MATLAB-Datei angezeigt werden. Ich habe versucht, dies mit grep zu tun, konnte aber den richtigen regulären Ausdruck nicht herausfinden.
Gdalya
@Gdalya Ich hoffe , die folgende Pipeline dies tun wird (keine Tests perfomed wurden): cat matlab.git.diff | sed -e '/^\+[ ]*.*\%$/d' | wc -l. /regexp/dlöscht eine übereinstimmende Zeile regexpund -eaktiviert eine angemessene (IMNSHO) Syntax für regexp.
dbanet
2
Warum nicht einfach grep -v '^+ *%' matlab.git.diff | wc -l?
Celtschk
@celtschk, solange dies in Kommentarzeilen üblich ist: Ist es möglich, Ihren grepBefehl zu ändern, um ihn als Kommentar zu betrachten, z. B. " + Hello"(Leerzeichen vor dem +)?
Sopalajo de Arrierez
1
@SopalajodeArrierez: Natürlich ist es möglich: grep -v '^ *+' matlab.git.diff | wc -l(Ich gehe davon aus, dass die Anführungszeichen eigentlich nicht Teil der Zeile waren; ich gehe auch davon aus, dass beide Zeilen mit und ohne Leerzeichen vor dem +Kommentar sein sollen; wenn um Mindestens ein Leerzeichen ist obligatorisch (entweder ersetzen Sie den Stern *durch \+oder fügen Sie einfach ein weiteres Leerzeichen vor dem Stern hinzu). Wahrscheinlich möchten Sie statt nur Leerzeichen beliebige Leerzeichen verwenden. Ersetzen Sie dazu das Leerzeichen durch [[:space:]]. Beachten Sie, dass ich auch das Matching entfernt habe, %da es nicht in Ihrem Beispiel ist.
Celtschk
15

Wie Michael sagte, wc -list der Weg zu gehen. Aber nur für den Fall , dass Sie aus unerklärlichen Gründen bash, perloder awkaber nicht wc, hier sind ein paar Lösungen:

Nur Bash

$ LINECT=0; while read -r LINE; do (( LINECT++ )); done < file.txt; echo $LINECT

Perl-Lösungen

$ perl -lne 'END { print $. }' file.txt

und die weit weniger lesbar:

$ perl -lne '}{ print $.' file.txt

Awk-Lösung

$  awk 'END {print NR}' file.txt
Steven D
quelle
15

Steven D hat GNU vergessen sed:

sed -n '$=' file.txt

Wenn Sie die Anzahl ohne Ausgabe des Dateinamens ermitteln möchten und Folgendes verwenden wc:

wc -l < file.txt

Nur zum Teufel:

cat -n file.txt | tail -n 1 | cut -f1
Dennis Williamson
quelle
2
Oder grep -c '', oder tr -dc '\n' | wc -c, oder nl -ba -nln | tail -n 1 |sed -e 's/[^0-9].*//'... Ist irgendetwas von diesen an sich nützlich (im Gegensatz zu Dingen, auf denen man aufbauen muss, um ein Programm zu erstellen, das mehr als das Zählen von Zeilen leistet) als wc -lund reines (ba) sh?
Gilles ‚SO- Anschlag, der böse‘
1
@Gilles: Ich denke, der Ausdruck "viele Wege" in der Frage hat eine Herausforderung ausgelöst, zu der Steve und ich aufgestiegen sind.
Dennis Williamson
1
@ Gilles:sed 's/.*//' file.txt | uniq -c
Dennis Williamson
2
@ Gilles: Oh, du meintest zuerst . uniq -c -w 0 file.txtund du kannst cut -c -7nur die nummer behalten. Oder mehr POSIXly: uniq -c file.txt | awk '{c+=$1}END{print c}'. Wie wäre es dc(obwohl es nicht POSIX ist)? uniq -c file.txt | cut -c -7 | sed '$alax' | dc -e '[pq]sb[+z1=blax]sa' -. bcPOSIX ist: uniq -c file.txt | cut -c -7 | sed -n ':a;${s/\n/ + /gp;b};N;ba' | bc. Die einfache Antwort , wenn Sie davon ausgehen , eine begrenzte Leitungslänge: uniq -c -f 100000 file.txt.
Dennis Williamson
1
@ JosipRodin: Zitate hinzugefügt
Dennis Williamson
11

Wort der Warnung bei der Verwendung

wc -l

Weil wc -l durch Zählen von \ n funktioniert. Wenn die letzte Zeile in Ihrer Datei nicht effektiv in einer neuen Zeile endet, ist die Zeilenzahl um 1 niedriger. (Daher belässt die alte Konvention die neue Zeile am Ende Ihrer Datei.)

Da ich nie sicher sein kann, ob eine bestimmte Datei der Konvention folgt, die letzte Zeile mit einer neuen Zeile zu beenden, empfehle ich, einen dieser alternativen Befehle zu verwenden, der die letzte Zeile in die Zählung einbezieht, unabhängig davon, ob eine neue Zeile eingegeben wurde oder nicht.

sed -n $= filename
perl -lne 'END { print $. }' filename
awk 'END {print NR}' filename
grep -c '' filename
Brezeln1337
quelle
schöne zusammenfassung. Und willkommen bei Unix & Linux
Sebastian
Hm ist das letzte Stück wirklich Linie?
Gena2x
1
Ich bin mir sicher, dass es von der Verwendung durch jeden abhängt. denn das letzte Stück ist normalerweise eine Textzeile, die jemand nicht mit einer neuen Zeile abschließt. Der häufigste Verwendungszweck ist eine Datei mit einer einzelnen Textfolge, die nicht in einer neuen Zeile endet. wc -l würde dies als "0" zählen, wenn ich sonst eine Zählung von "1" erwarten würde.
Brezeln1337
3

Falls Sie nur bash und absolut keine externen Tools zur Verfügung haben, können Sie auch Folgendes tun:

count=0
while read
do
  ((count=$count+1))
done <file.txt
echo $count

Erläuterung: Die Schleife liest die Standardeingabe zeilenweise ( readda wir mit der Leseeingabe sowieso nichts anfangen, wird keine Variable zum Speichern bereitgestellt) und erhöht die Variable countjedes Mal. Aufgrund der Umleitung ( <file.txtnach done) ist die Standardeingabe für die Schleife von file.txt.

Celtschk
quelle
2

Sie können den Befehl jederzeit grepwie folgt verwenden:

grep -c "^" file.txt

Es werden alle tatsächlichen Zeilen gezählt file.txt, unabhängig davon , ob die letzte Zeile am Ende ein LF-Zeichen enthält oder nicht.

Paolo
quelle