Wenn Sie Zeilen mit wc zählen, geben Sie keinen Fehler aus, wenn es sich um ein Verzeichnis handelt

12

Ich möchte die Gesamtanzahl der Zeilen in allen /etcDateien zählen, aber nicht die Dateien in den Unterverzeichnissen. Deshalb habe ich Folgendes eingegeben: wc -l /etc/* | tail -1und die Ausgabe sieht folgendermaßen aus:

xxxx is a directory 
yyyy is a directory
total 1752

Meine Frage ist, wie ich diese Kommentare entfernen (löschen) kann und gibt es eine bessere Möglichkeit, diese Art der Zählung durchzuführen?

Hamza
quelle
1
Ich denke, dass mit find nicht 100% wright ist, denn in / etc gibt es nicht nur reguläre Dateien f, sondern auch Links l. Daher ist diese Version viel besser: $ sudo wc -l / etc / * 2> / dev / null | Schwanz -1
Hamza

Antworten:

14

Sie können die Fehlermeldungen nach / dev / null ausgeben

$ wc -l /etc/* 2>/dev/null | tail -1

Mit diesem Befehl sehen Sie nur die Anzahl der Zeilen in den Dateien, die weltweit lesbar sind. Um die Anzahl der Zeilen aller Dateien zu sehen, müssten Sie den Befehl mit erhöhen sudo.

$ sudo wc -l /etc/* 2>/dev/null | tail -1
LD James
quelle
8

Isolieren Sie Dateien und führen Sie wc auf ihnen aus

Was wc -l /etc/*tut , ist , dass *für alle Elemente innerhalb erweitern /etc/Verzeichnis. Ziel ist es also, Dateien zu isolieren und zu bearbeiten wc. Es gibt verschiedene Möglichkeiten, dies zu tun.

for Schleife mit Test

Der testBefehl, oder häufiger abgekürzt als, [kann verwendet werden, um festzustellen, ob ein Element eine reguläre Datei ist:

[ -f "$FILE" ]

Wir können also alle Elemente in iterieren und nur /etc/ausführen, wcwenn der obige Befehl true zurückgibt. Wie so:

for i in /etc/*; do [ -f "$i" ] && wc -l "$i" ; done             

finden

Wir können auch verwenden , findmit -maxdepth, -typeund -execFahnen

find /etc/ -maxdepth 1 \( -type f -o -type l \) -exec wc -l {} +

  • -maxdepthInformiert Sie darüber, wie tief die Verzeichnisstruktur noch reicht. Der Wert 1 bedeutet nur die Dateien im gewünschten Verzeichnis.
  • -type f-oWeist es an, nach regulären Dateien zu suchen, ODER (dargestellt durch Flag) nach sybolischen Links (dargestellt durch type l). All diese Güte ist in Klammern eingeschlossen, ()die mit einem \Escapezeichen versehen sind, damit die Shell sie als Teil von to interpretiertfind Befehls , und nicht als etwas anderes.
  • -exec COMMAND {} +Die Struktur hier führt den Befehl aus, den wir ihm geben, +und gibt an, dass alle gefundenen Dateien als Befehlszeilenargumente für den Befehl gespeichert werden sollen.

Um insgesamt zu produzieren, konnten wir die Ausgabe nach tailBelieben leiten

$ find /etc/ -maxdepth 1 \( -type f -o -type l \) -exec wc -l {} + | tail -n 1           
[sudo] password for xieerqi: 
 11196  total

Randnotiz

Es ist einfacher, es einfach zu verwenden wc -l /etc/* 2>/dev/null | tail -1, wie in der Antwort von LD James, findsollte jedoch Teil der Gewohnheit sein, mit Dateien umzugehen, um die Verarbeitung schwieriger Dateinamen zu vermeiden. Für weitere Informationen lesen Sie den Aufsatz Wie man richtig mit Dateinamen umgeht

Sergiy Kolodyazhnyy
quelle
5

find macht das einfach:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*')

Ausgabe:

...
828 /etc/mime.types
25 /etc/ts.conf
66 /etc/inputrc
 0 /etc/subgid-
8169 total

ABER wenn du nur die Nummer als Ausgabe haben willst und sonst nichts:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*') | grep total | awk '{print $1}'

BEARBEITEN : newlinesFehler kos sagte vorherrscht. Nur mit -execkorrigiert es. Enthält /etcauch keine solchen Dateien.

Ausgabe:

8169

Wie von kos gezeigt , kann der obige Befehl auf Folgendes reduziert werden:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*') | awk 'END {print $1}'

BEARBEITEN : newlinesFehler kos sagte vorherrscht. Nur mit -execkorrigiert es. Enthält /etcauch keine solchen Dateien.

Ausgabe:

8169
Raphael
quelle
4
Was ist der Zweck von -iname '*'? stimmt nicht findalles standardmäßig überein?
Steeldriver
@steeldriver - Ohne hat es bei mir nicht funktioniert '*'.
Raphael
2

Verwenden Sie z-shell ( zsh), die Königin der Muscheln , anstatt bash.

sudo wc -l /etc/*(.) | tail -1
AB
quelle