Wie kann man "wc -l" dazu bringen, nur die Anzahl der Zeilen ohne Dateinamen zu drucken?

154
wc -l file.txt

gibt die Anzahl der Zeilen und den Dateinamen aus.

Ich brauche nur die Nummer selbst (nicht den Dateinamen).

Ich kann dies tun

 wc -l file.txt | awk '{print $1}'

Aber vielleicht gibt es einen besseren Weg?

PoGibas
quelle
13
wc -l < file.txterledigt die Arbeit präzise und präzise.
Jonathan Leffler
2
Mögliches Duplikat von nur die ganze Zahl von wc in Bash bekommen
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
3
Dies ist eine Frage, die ich jetzt zweimal nachgeschlagen habe. Dieses Verhalten von wc ist nicht intuitiv und antiparadigmatisch für die übliche Knappheit. Diese Knappheit gibt es aus einem Grund, weil Sie genau nicht alle Arten von flauschiger Redundanz umgehen wollen. Immerhin kenne ich den Dateinamen, nicht wahr? Was ich will, ist die Zeilenanzahl.
Peter - Stellen Sie Monica

Antworten:

216

Versuchen Sie Folgendes:

wc -l < file.txt
Norman Ramsey
quelle
5
In AIX, ksh, steht vor der Nummer immer ein Leerzeichen. Wir müssen | verwenden awk '{print $ 1}' oder ein Schnitt, um die Leerzeichen abzuschneiden. Eine andere Möglichkeit zum Trimmen wäre, ein Echo einzuschließen.
Rao
@rao ist korrekt, dies fügt ein Leerzeichen vor der Nummer hinzu. Meine Lösung löst dies und ist einfacher als awk oder cut.
Desi Cochrane
@rao Es gibt keinen Platz mit Bash. Woher kommt der Raum in ksh? wc -lsollte keine ausgeben, und warum sollte ksh der Standardausgabe eines Programms ein Leerzeichen voranstellen?
Peter - Monica
Dies ist zwar die richtige Problemumgehung (und es ist einfach genug, dass wc nie geändert wurde), aber wahrscheinlich langsamer und nicht intuitiv. Zum einen würde ich so etwas wie 4711 [stdin]die Ausgabe erwarten .
Peter - Reinstate Monica
Erwägen Sie auch das Pairing mit printf "%'d", wodurch der Platz geschont und große Zahlen schön ausgedruckt werden.
Leo
21
cat file.txt | wc -l

Laut Manpage (für die BSD-Version muss ich keine GNU-Version überprüfen):

Wenn keine Dateien angegeben sind, wird die Standardeingabe verwendet und kein Dateiname angezeigt. Die Eingabeaufforderung akzeptiert Eingaben bis zum Empfang von EOF oder [^ D] in den meisten Umgebungen.

pjmorse
quelle
3
Ich mag keine Katze - die Verkettung nimmt zu viel Zeit in Anspruch.
PoGibas
9
wc -l < file.txthat den gleichen Effekt.
pjmorse
@user: Teste es. Der mit Abstand langsamste Teil ist das Lesen der Datei von der Festplatte.
Sarnold
11
@ user1286528 dann verwenden wc -l < file.txt, um die nutzlose Verwendung von Katze zu vermeiden. Obwohl Sie absolut verrückt sind, wenn Sie denken, dass dies spürbare Zeit in Anspruch nimmt.
Hobbs
12

Um dies ohne den führenden Raum zu tun, warum nicht:

wc -l < file.txt | bc
Desi Cochrane
quelle
Ich bekomme Syntaxfehler damit (Ubuntu 14.04). Ich denke, es gibt ein Problem mit dem Dateinamen.
MERose
Auf einem RHEL 6.7 werden Fehler ausgegeben: $ wc -l file.csv | bc (standard_in) 1: Syntaxfehler (standard_in) 1: unzulässiges Zeichen: N (standard_in) 1: Syntaxfehler (standard_in) 1: Syntaxfehler
Rodrigo Hjort
3
Ich erhalte auch einen Analysefehler, aber Sie können diesen mit der anderen Antwort kombinieren wc -l < file.txt, um den wc -l < file.txt | bc
Analysefehler
11

Wie wäre es mit

wc -l file.txt | cut -d' ' -f1

dh die Ausgabe von wcin cutweiterleiten (wobei Trennzeichen Leerzeichen sind und nur das erste Feld auswählen)

Neil Albert
quelle
4
Das ist nicht besser als das wc -l file.txt | awk '{print $1}'OP versucht hat.
DoubleDown
1
Schneller als die wc -l < file.txtMethode. Muss aber | cut -d' ' -f2auf BSD verwendet werden, solange der wcBefehl ein führendes Leerzeichen zurückgibt, Beispiel: "34068289 file.txt" anstelle von "34068289 file.txt".
Sopalajo de Arrierez
@doubleDown Nun, die Verwendung von awk ist wie die Verwendung einer CNC-Maschine zum Schneiden einer Platte anstelle einer Säge. Verwenden Sie zum Sägen eine Säge.
Peter - Stellen Sie Monica
5

Vergleich der Techniken

Ich hatte ein ähnliches Problem beim Versuch, eine Zeichenanzahl ohne das von bereitgestellte führende Leerzeichen zu erhalten wc, was mich zu dieser Seite führte. Nachdem ich die Antworten hier ausprobiert habe, sind die folgenden Ergebnisse meiner persönlichen Tests auf einem Mac (BSD Bash). Auch dies ist für die Anzahl der Zeichen; für die Zeilenanzahl würden Sie tun wc -l. echo -nlässt den Zeilenumbruch weg.

FOO="bar"
echo -n "$FOO" | wc -c                          # "       3"    (x)
echo -n "$FOO" | wc -c | bc                     # "3"           (√)
echo -n "$FOO" | wc -c | tr -d ' '              # "3"           (√)
echo -n "$FOO" | wc -c | awk '{print $1}'       # "3"           (√)
echo -n "$FOO" | wc -c | cut -d ' ' -f1         # "" for -f < 8 (x)
echo -n "$FOO" | wc -c | cut -d ' ' -f8         # "3"           (√)
echo -n "$FOO" | wc -c | perl -pe 's/^\s+//'    # "3"           (√)
echo -n "$FOO" | wc -c | grep -ch '^'           # "1"           (x)
echo $( printf '%s' "$FOO" | wc -c )            # "3"           (√)

Ich würde mich cut -f*im Allgemeinen nicht auf die Methode verlassen, da Sie die genaue Anzahl der führenden Leerzeichen für eine bestimmte Ausgabe kennen müssen. Und der grepeine dient zum Zählen von Zeilen, aber nicht von Zeichen.

bcist am prägnantesten awkund perlscheint ein bisschen übertrieben, aber sie sollten alle relativ schnell und tragbar genug sein.

Beachten Sie auch, dass einige davon angepasst werden können, um umgebende Leerzeichen auch von allgemeinen Zeichenfolgen zu trennen (zusammen mit echo `echo $FOO`einem weiteren netten Trick).

Beejor
quelle
1
echo $(printf '%s' "$FOO" | wc -c)ist eine der seltenen echoSituationen, in denen mit einem Befehl Subshitution nicht nutzlos ist.
Tripleee
@tripleee Whoa ... verhält sich basierend auf Ihrem Code echo `echo $FOO`;auch wie ein String.trim () -Befehl für eine Variable! Das ist unglaublich praktisch. Ich werde auch Ihre Zeile zu meiner Antwort hinzufügen.
Beejor
Vielleicht für den Kontext siehe auch Wann Anführungszeichen um eine Shell-Variable zu wickeln sind
Tripleee
4

Wie wäre es mit

grep -ch "^" file.txt
MeIsMich
quelle
3
Nett. Sehr originelle / kreative Verwendung, grepaber wenn ich dies überprüfe, stellt sich heraus (nicht überraschend), dass es 2x bis 6x langsamer ist als die einfachere / unkomplizierte wcMethode in meinen Tests.
Arielf
3

Offensichtlich gibt es dafür viele Lösungen. Hier ist noch eine:

wc -l somefile | tr -d "[:alpha:][:blank:][:punct:]"

Dies gibt nur die Anzahl der Zeilen aus, aber das nachfolgende Zeilenumbruchzeichen ( \n) ist vorhanden. Wenn Sie dies auch nicht möchten, ersetzen Sie es [:blank:]durch [:space:].

Bouchaala Reda
quelle
Dies hat das Problem, wenn der Dateiname eine Nummer enthält. Zum Beispiel für die Datei test9mit 1 Zeile wird die Ausgabe 19 sein.
Raphael Ahrens
1

Der beste Weg wäre, zuerst alle Dateien im Verzeichnis zu finden und dann AWK NR (Number of Records Variable) zu verwenden.

unten ist der Befehl:

find <directory path>  -type f | awk  'END{print NR}'

Beispiel: - find /tmp/ -type f | awk 'END{print NR}'

user128364
quelle
0

Dies funktioniert bei mir mit dem Normalen wc -lund sedum jedes Zeichen zu entfernen, das keine Zahl ist.

wc -l big_file.log | sed -E "s/([a-z\-\_\.]|[[:space:]]*)//g"

# 9249133
joseluisq
quelle