Hoe kan ik een telling van bestanden in een directory krijgen met behulp van de opdrachtregel?

Ik heb een map met een groot aantal bestanden. Ik zie geen ls optie om het aantal te bepalen. Is er een commandoregel magie om een telling van bestanden te krijgen?

Oplossing

Gebruik makend van een brede definitie van "bestand";

ls | wc -l

(merk op dat verborgen bestanden niet worden meegeteld en dat wordt aangenomen dat bestandsnamen geen newline-tekens bevatten).

Om verborgen bestanden (behalve . en ..) op te nemen en problemen met newline-tekens te vermijden, is de canonieke manier:

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

Of recursief:

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

Voor een enge definitie van bestand:

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

Als je weet dat de huidige directory ten minste één niet verborgen bestand bevat:

set -- *; echo "$#"

Dit is natuurlijk generaliseerbaar naar elke glob.

In een script heeft dit het soms ongelukkige neveneffect dat de positionele parameters worden overschreven. Je kunt dat omzeilen door een subshell te gebruiken of met een functie (Bourne/POSIX versie) als:

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

Een alternatieve oplossing is $(ls -d -- * | wc -l). Als de glob * is, kan het commando worden verkort tot $(ls | wc -l). Het parseren van de uitvoer van ls maakt me altijd ongemakkelijk, maar hier zou het moeten werken, zolang je bestandsnamen geen newlines bevatten, of je ls ze escaped. En $(ls -d -- * 2>/dev/null | wc -l) heeft het voordeel dat het het geval van een niet overeenkomende glob netjes afhandelt (d.w.z., het geeft 0 terug in dat geval, terwijl de set * methode vereist dat je moeilijk moet testen of de glob misschien leeg is).

Als bestandsnamen newline-tekens kunnen bevatten, is een alternatief om $(ls -d ./* | grep -c /) te gebruiken.

Elk van deze oplossingen die gebaseerd is op het doorgeven van de uitbreiding van een glob aan ls kan mislukken met een argument list too long error als er veel overeenkomende bestanden zijn.

Commentaren (6)