In diesem ls -1 target_dir | wc -l
Fall werden die Dateien in einem Verzeichnis gezählt. Das finde ich etwas umständlich. Gibt es einen eleganteren oder prägnanteren Weg?
ubuntu
command-line
filesystems
Codecowboy
quelle
quelle
ls
gibt schon die Gesamtzahl an, also wie wäre esls -l | head -1
? Machen Sie es zu einem Alias, wenn Sie etwas kürzeres wollen.ls -l
gibt die Gesamtgröße der Dateien an, nicht die Anzahl der Dateien.ls | wc -l
dass Sie die falsche Anzahl erhalten, wenn Dateinamen Zeilenumbrüche enthalten.stat -c %h .
gibt die gleichen Informationen wiels -ld . | cut -d" " -f 2
Antworten:
Angenommen, bash 4+ (welches jede unterstützte Version von Ubuntu hat):
Nennen Sie es als
num_files [dir]
.dir
ist optional, ansonsten wird das aktuelle Verzeichnis verwendet. In Ihrer Originalversion werden ausgeblendete Dateien nicht berücksichtigt. Dies gilt auch nicht für diese. Wenn du das willst,shopt -s dotglob
vorherset -- *
.Ihr ursprüngliches Beispiel enthält nicht nur reguläre Dateien, sondern auch Verzeichnisse und andere Geräte. Wenn Sie wirklich nur reguläre Dateien (einschließlich Symlinks zu regulären Dateien) möchten, müssen Sie diese überprüfen:
Wenn Sie GNU find haben, ist so etwas auch eine Option (beachten Sie, dass dies versteckte Dateien enthält, die Ihr ursprünglicher Befehl nicht ausgeführt hat):
(Wechseln Sie
-type
zu,-xtype
wenn Sie auch Symlinks zu regulären Dateien zählen möchten.)quelle
set
scheitern, wenn es sehr viele Dateien gibt? Ich denke, Sie müssen möglicherweise einenxargs
Summierungscode verwenden, damit dies im allgemeinen Fall funktioniert.shopt -s dotglob
wenn Sie möchten, dass Dateien beginnend mit.
gezählt werdenset
das unter diesen Umständen scheitern wird, da wir eigentlich keine machenexec
. Das heißt, auf meinem Systemgetconf ARG_MAX
ergibt sich 262144, aber wenn ich das tuetest_arg_max() { set -- {1..262145}; echo $#; }; test_arg_max
, antwortet es glücklich 262145.-maxdepth
ist kein POSIX.f=(target_dir/*);echo ${#f[*]}
Funktioniert korrekt für Dateien mit Leerzeichen, Zeilenumbrüchen usw. im Namen.
quelle
ls
ist nur mehrspaltig, wenn es direkt an ein Terminalwc
ausgegeben wird , können Sie die Option "-1" entfernen, Sie können die Option "-l" entfernen , nur den ersten Wert lesen (träge Lösung, nicht für rechtliche Beweise zu verwenden, strafrechtliche Ermittlungen, missionskritische, taktische Operationen ..).quelle
wc
, um die Anzahl der Dateien in einem einfachen Fall zu ermitteln. Wie ist das überhaupt eine Lösung?target
es sich um einen Glob handelt, der, wenn er erweitert wird, einige Dinge enthält, die mit Bindestrichen beginnen.touch -- {1,2,3,-a}.txt && ls *|wc
rm -- *.txt
wc -l
? Andernfalls erhalten Sie Zeilenumbrüche, Wörter und Bytes für diels
Ausgabe. Das hat David Richerby gesagt: Man muss es noch einmal analysieren.wc
kein Argument, das Sie nicht analysieren müssen, wenn Ihr Gehirn weiß, dass das erste Argument Newline ist.Wenn es Prägnanz sind Sie nach ( und nicht genauer Richtigkeit , wenn sie mit Dateien mit Zeilenumbrüchen in ihrem Namen zu tun, etc.), empfehle ich nur Aliasing
wc -l
zulc
( „Zeilenzahl“):Wie andere angemerkt haben, brauchen Sie diese
-1
Option nichtls
, da dies automatischls
geschieht, wenn in eine Pipe geschrieben wird. (Es sei denn, Sie haben sich daraufls
geeinigt, immer den Spaltenmodus zu verwenden. Ich habe das schon einmal gesehen, aber nicht sehr oft.)Ein
lc
Alias ist im Allgemeinen sehr praktisch, und wenn Sie sich den Fall "count the current directory" ansehen,ls|lc
ist diese Frage so kurz wie möglich.quelle
Bisher ist Aarons Ansatz der einzige, der prägnanter ist als Ihr eigener. Eine korrektere Version Ihres Ansatzes könnte folgendermaßen aussehen:
Das listet rekursiv alle Dateien auf - keine Verzeichnisse - eine pro Zeile, einschließlich .dot-Dateien unter dem aktuellen Verzeichnis, wobei Shell-Globs verwendet werden, um nicht druckbare Zeichen zu ersetzen. grep filtert alle übergeordneten Verzeichnislisten oder .. oder * / oder Leerzeilen aus. Es sollte also nur eine Zeile pro Datei vorhanden sein, deren Gesamtanzahl grep an Sie zurückgibt. Wenn Sie möchten, dass auch untergeordnete Verzeichnisse einbezogen werden, gehen Sie wie folgt vor:
Entfernen Sie
-R
in beiden Fällen die Option, wenn Sie keine rekursiven Ergebnisse erhalten möchten.quelle
find
. Wenn Sie nur eine Zählung wünschen, sollte dies funktionieren:find -mindepth 1 -maxdepth 1 -printf '\n'|wc -l
(Entfernen Sie die Tiefensteuerelemente, um rekursive Ergebnisse zu erhalten).find . \! -name . -prune | wc -l
- was natürlich immer noch nicht funktioniert.printf
Anweisung gibt eine konstante Zeichenfolge (eine neue Zeile) aus, die den Dateinamen überhaupt nicht enthält, sodass die Ergebnisse unabhängig von seltsamen Dateinamen sind. Dieser Trick ist mit einemfind
nicht unterstützten Trickprintf
natürlich überhaupt nicht möglich .find .//. \!. -name . -prune | grep -c '^\.//\.'
/
Da die.//.
Sequenz das einzige andere Zeichen ist, das nicht in Dateinamen vorkommt, wird sie garantiert für jede Datei genau einmal angezeigt, oder? Ein paar Fragen - warum.//.
und warum-prune
? Wann würde das anders seinfind . \! -name . | grep -c '^\.'
? (Ich nehme an, das.
in Ihrem\!.
ist ein Tippfehler.)