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?
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 //
For en snæver definition af fil:
find . -maxdepth 1 -type f | wc -l
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.