Hvordan kan jeg få en optælling af filer i en mappe ved hjælp af kommandolinjen?

Jeg har en mappe med et stort antal filer. Jeg kan ikke se en ls-switch til at angive antallet. Er der en eller anden kommandolinje magi til at få en optælling af filer?

Løsning

Ved at bruge en bred definition af "fil"

ls | wc -l

(bemærk, at den ikke tæller skjulte filer med og antager, at filnavne ikke indeholder newline-tegn).

For at inkludere skjulte filer (undtagen . og ..) og undgå problemer med newline-tegn, er den kanoniske måde at gøre det på:

find . ! -name . -prune -print | grep -c /

Eller rekursivt:

find .//. ! -name . -print | grep -c //
Kommentarer (6)

For en snæver definition af fil:

 find . -maxdepth 1 -type f | wc -l
Kommentarer (4)

Hvis du ved, at den aktuelle mappe indeholder mindst én ikke-skjult fil:

set -- *; echo "$#"

Dette kan naturligvis generaliseres til enhver glob.

I et script har dette den undertiden uheldige bivirkning at overskrive positionsparametrene. Du kan omgå dette ved at bruge en subshell eller med en funktion (Bourne/POSIX-version) som f.eks:

count_words () {
  eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"

En alternativ løsning er $(ls -d -- * | wc -l). Hvis glob'en er *, kan kommandoen forkortes til $(ls | wc -l). Parsing af output af ls gør mig altid urolig, men her burde det virke, så længe dine filnavne ikke indeholder newlines, eller din ls undgår dem. Og $(ls -d -- * 2>/dev/null | wc -l) har den fordel, at den håndterer tilfælde af en ikke-matchende glob elegant (dvs. den returnerer 0 i det tilfælde, hvorimod set *-metoden kræver en besværlig test af, om glob'en måske er tom).

Hvis filnavne kan indeholde newline-tegn, er et alternativ at bruge $(ls -d ./* | grep -c /).

Enhver af disse løsninger, der er afhængige af at overdrage udvidelsen af en glob til ls, kan fejle med en argument list too long-fejl, hvis der er mange matchende filer.

Kommentarer (6)