Ako môžem získať počet súborov v adresári pomocou príkazového riadku?

Mám adresár s veľkým počtom súborov. Nevidím prepínač ls, ktorý by poskytol počet. Existuje nejaké kúzlo príkazového riadku na získanie počtu súborov?

Riešenie

Použitie širokej definície pojmu "súbor"

ls | wc -l

(všimnite si, že nepočíta so skrytými súbormi a predpokladá, že názvy súborov neobsahujú znaky nového riadku).

Ak chcete zahrnúť skryté súbory (okrem . a ..) a vyhnúť sa problémom so znakmi nového riadku, kanonický spôsob je:

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

Alebo rekurzívne:

find .//. ! -name . -print | grep -c //
Komentáre (6)

Pre užšiu definíciu súboru:

 find . -maxdepth 1 -type f | wc -l
Komentáre (4)

Ak viete, že aktuálny adresár obsahuje aspoň jeden neskrytý súbor:

set -- *; echo "$#"

Toto je samozrejme možné zovšeobecniť na akýkoľvek glob.

V skriptoch to má niekedy nešťastný vedľajší účinok v podobe prepísania pozičných parametrov. Môžete to obísť použitím podskupiny alebo pomocou funkcie (verzia Bourne/POSIX), ako napr:

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

Alternatívnym riešením je $(ls -d -- * | wc -l). Ak je glob *, príkaz sa dá skrátiť na $(ls | wc -l). Rozbor výstupu príkazu ls ma vždy znepokojuje, ale tu by to malo fungovať, pokiaľ názvy súborov neobsahujú nové riadky, alebo ich váš ls escapuje. A $(ls -d -- * 2>/dev/null | wc -l) má tú výhodu, že sa elegantne vysporiada s prípadom nezhodného globu (t. j. v takom prípade vráti 0, zatiaľ čo metóda set * vyžaduje zložité testovanie, či glob môže byť prázdny).

Ak názvy súborov môžu obsahovať znaky nového riadku, alternatívou je použitie $(ls -d ./* | grep -c /).

Každé z týchto riešení, ktoré sa spoliehajú na odovzdanie rozšírenia globu do ls, môže zlyhať s chybou argument list too long (zoznam argumentov je príliš dlhý), ak je veľa vyhovujúcich súborov.

Komentáre (6)