Bash-Echo Anzahl der in einer Bash-Variablen angegebenen Dateizeilen ohne Dateinamen

79

Ich habe die folgenden drei Konstrukte in einem Bash-Skript:

NUMOFLINES=$(wc -l $JAVA_TAGS_FILE)
echo $NUMOFLINES" lines"

echo $(wc -l $JAVA_TAGS_FILE)" lines"

echo "$(wc -l $JAVA_TAGS_FILE) lines"

Und beide erzeugen identische Ausgabe, wenn das Skript ausgeführt wird:

121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines

Dh der Name der Datei wird ebenfalls wiedergegeben (was ich nicht möchte). Warum schlagen diese Scriplets fehl und wie soll ich ein Clean ausgeben:

121711 lines

?

Marcus Junius Brutus
quelle
Mögliches Duplikat von nur die ganze Zahl von wc in bash bekommen
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

Antworten:

156

Ein Beispiel mit Ihren eigenen Daten

Sie können vermeiden, dass Ihr Dateiname in die Variable NUMOFLINES eingebettet wird , indem Sie die Umleitung von JAVA_TAGS_FILE verwenden , anstatt den Dateinamen als Argument an wc zu übergeben . Zum Beispiel:

NUMOFLINES=$(wc -l < "$JAVA_TAGS_FILE")

Erläuterung: Verwenden Sie Pipes oder Umleitung, um Dateinamen in der Ausgabe zu vermeiden

Das Dienstprogramm wc druckt den Namen der Datei in seiner Ausgabe nicht, wenn die Eingabe von einem Pipe- oder Umleitungsoperator stammt. Betrachten Sie diese verschiedenen Beispiele:

# wc shows filename when the file is an argument
$ wc -l /etc/passwd
41 /etc/passwd

# filename is ignored when piped in on standard input
$ cat /etc/passwd | wc -l
41

# unusual redirection, but wc still ignores the filename
$ < /etc/passwd wc -l
41

# typical redirection, taking standard input from a file
$ wc -l < /etc/passwd
41

Wie Sie sehen können, druckt wc den Dateinamen nur, wenn er als Argument und nicht als Daten für die Standardeingabe übergeben wird. In einigen Fällen möchten Sie möglicherweise, dass der Dateiname gedruckt wird. Daher ist es hilfreich zu verstehen, wann er angezeigt wird.

Todd A. Jacobs
quelle
1
Beachten Sie, dass dieser Ansatz nicht die letzte Zeile enthält, wenn die letzte Zeile nicht mit dem Zeilenendezeichen endet. Siehe meinen Fix unten.
Ling
15

wc Ich kann den Dateinamen nicht erhalten, wenn Sie ihm keinen geben.

wc -l < "$JAVA_TAGS_FILE"
Ignacio Vazquez-Abrams
quelle
2
Na dann nicht. Übergeben Sie die Datei einfach an wcstdin, wie in der Antwort gezeigt. Also cat "$JAVA_TAGS_FILE" | wc -loder gleichwertig wc -l < "$JAVA_TAGS_FILE". Auf diese Weise werden wcnur Rohdaten abgerufen, nicht der Dateiname.
Witiko
12

Sie können auch awk verwenden:

awk 'END {print NR,"lines"}' filename

Oder

awk 'END {print NR}' filename

Javier López
quelle
5

(auf Mac und wahrscheinlich auch auf anderen Unixen anwenden)

Tatsächlich gibt es ein Problem mit dem wc-Ansatz: Er zählt nicht die letzte Zeile, wenn er nicht mit dem Zeilenende-Symbol endet.

Verwenden Sie dies stattdessen

nbLines=$(cat -n file.txt | tail -n 1 | cut -f1 | xargs)

oder noch besser (danke gniourf_gniourf):

nblines=$(grep -c '' file.txt)

Hinweis: Der awk-Ansatz von chilicuil funktioniert ebenfalls.

ling
quelle
2
Sehr verschlungene Methode! Vielleicht möchten Sie nblines=$(grep -c '' file)stattdessen (was in diesem Fall die kanonische Methode ist, unvollständige Zeilen zu zählen). Beachten Sie jedoch, dass Sie laut POSIX die unvollständigen Zeilen (und nicht die Zeilen ) zählen. Sie haben es tatsächlich mit einer Binärdatei und nicht mit einer Textdatei zu tun .
gniourf_gniourf
@gniourf_gniourf Danke, das wusste ich nicht, es funktioniert großartig und ist noch prägnanter.
Ling
es ist vielleicht eine bessere Lösungnblines=$(($(cat "file.txt" | wc -l) + 1))
Andrey Izman
3

Es ist sehr einfach:

NUMOFLINES=$(cat $JAVA_TAGS_FILE | wc -l )

oder

NUMOFLINES=$(wc -l $JAVA_TAGS_FILE | awk '{print $1}')
Slava Semushin
quelle
Der erste ist nutzlose Verwendung von Katze.
Kap
@kap Nein, es sieht nur so aus. Wenn Sie loswerden cat, hätten Sie das 2. Beispiel, weil es wc -l2 Spalten zurückgibt, wenn es nur mit einer Datei verwendet wird.
Slava Semushin
-3

Normalerweise benutze ich die 'Back Tick'-Funktion von Bash

export NUM_LINES=`wc -l filename`

Beachten Sie, dass das 'Häkchen' das 'Zurück-Häkchen' ist, z. B. 'nicht das normale einfache Anführungszeichen

Russ Hore
quelle
5
Das ist nur eine andere Notation und löst nicht das Problem, dass der Dateiname Teil des Ergebnisses ist.
Izzy