Conta il numero totale di file in una determinata directory con estensione specifica


32

Voglio contare il numero totale di file in una directory particolare che termina con l'estensione ".mp4".

Ricevo il seguente comando:

ls -F |grep -v / | wc -l

Conta tutti i file in una directory particolare, ma voglio il conteggio dei file che terminano con l'estensione .mp4.

C'è qualche comando Ubuntu per quello?


2
La risposta semplice, corretta e diretta è @ louis-matthijssen one. ls -1la gestione dei caratteri di nuova riga rende, in questo caso, ragionevole analizzare il lsrisultato. Quello contrassegnato è errato per l'uso del flag -R.
Rmano,

Risposte:


19

Qui puoi fare così

ls -lR /path/to/dir/*.jpg | wc -l

Questo ti dà il conto


5
Perché il -R? Perché fare un full statquando hai solo bisogno del nome del file? Perché no ls -1 *.jpg| wc -l? (ok, non funziona se hai nomi di file con nuove righe. In tal caso te lo meriti ;-) ...)
Rmano

2
... e la domanda era "contare il numero di file in una directory". Inoltre, questo elencherà in modo ricorsivo tutto il contenuto delle sottodirectory il cui nome termina in .jpg , non i file nelle sottodirectory che terminano .jpg. L'hai mai provato?
Rmano,

1
La domanda dice "file in una directory specifica", il che implica che la ricorsione della sottodirectory non è desiderata.
David Richerby,

1
Questo fallisce anche se ci sono troppi file nella directory (perché *.jpgè espanso dalla shell, non da ls) e se ci sono file i cui nomi iniziano con trattini.
David Richerby,

2
@DavidRicherby Salta i nomi che iniziano con .. Ma in realtà funziona bene con trattini nei nomi, tranne quando /path/to/dirè la stringa vuota o un percorso relativo che inizia con un trattino. Ma prima ho sbagliato a dire che lssostituisce i personaggi ?. Ciò accade quando stdout è un terminale, ma qui l'output è una pipe, quindi lsinvia tutti i caratteri dai nomi dei file a wc. Ciò rende questa risposta errata senza il flag -qo -bper modificare tale comportamento , poiché i nomi dei file possono contenere righe. La risposta di l0b0 è libera da questi problemi.
Eliah Kagan,

42

Purtroppo questo problema benigno è difficile da risolvere in un modo che supporta tutti i nomi di file ed è portatile. Questo è sicuro (gestisce file nascosti, percorsi contenenti spazi, trattini e persino newline) e compatibili POSIX :

find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c

Se non vuoi che sia ricorsivo, aggiungi semplicemente -maxdepth 1.

Non devi analizzare l' lsoutput.

Test:

$ cd -- "$(mktemp -d)"
$ touch -- -foo.mp4 .bar.mp4 .bat.mp4 'baz.mp4
> ban.mp4'
$ find . -mindepth 1 -type f -name "*.mp4" -exec printf x \; | wc -c
4

Confronta con la risposta accettata :

$ ls -lR ./*.mp4 | wc -l
3

O altri suggerimenti:

$ find . -name "*.mp4" | wc -l
5
$ ls -1 *.mp4 | wc -l
ls: invalid option -- '.'
Try 'ls --help' for more information.
0
$ find . -name "*.mp4" | wc -c # Answer fixed at a later time
51
$ find . -name "*.mp4" | wc -l
5
$ find . | grep -i ".mp4$" | wc -l
5
$ ls . | grep ".mp4$" | wc -l
3

2
Sebbene questa risposta sia corretta e affidabile, è possibile utilizzare -printf xinvece di -exec printf x \;. Cioè: find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c non è necessario -execil printfcomando esterno , che se ci sono molti file sarà molto lento , perché finddeve sborsare (2) una copia di se stesso e quindi eseguire (2) /usr/bin/printf . Con -exec printf x \;, questo deve essere fatto una volta per ogni file .
Eliah Kagan,

-printfnon è supportato in POSIXfind , motivo per cui non l'ho usato.
l0b0,

1
Né sono -mindepthe -maxdepth, che hai usato.
Eliah Kagan,

Bene, non ci avevo capito!
l0b0,

BSD findcontiene -mindepthe -maxdepthnon contiene, -printfquindi apprezzo l'inclusione di entrambi.
Joseph,

11

Questo trova, ordina ed elenca tutti i file per estensione in ordine:

find . -type f | sed 's/.*\.//' | sort | uniq -c

Eccellente! Vorrei solo aggiungere un | sort -rnalla fine e forse un -mindepth 1dir se solo attuale.
Pablo A

E magari pipa per head -nottenere la cima n.
Raman,

così bella risposta, grazie mille
Dennis Golomazov il

5

Penso che sia molto semplice come i seguenti comandi.

$ find . -name "*.mp4" | wc -l
8

o

$ find . | grep -i ".mp4$" | wc -l
8

Penso che i comandi sopra calcolino il conteggio dei nomi di file e directory *.mp4

quindi ti suggerisco di usare l' -type fopzione come findparametro come segue.

$ find . -name "*.mp4" -type f | wc -l
8

Inoltre, ls -lRpuò essere utilizzato comefind .


2

Puoi usare ls -1 *.mp4 | wc -l.

Questo elencherà tutti i file che finiscono .mp4, stampando ogni file su una nuova riga ( ls -1 *.mp4), reindirizza l'output al wcquale conterà il numero di nuove righe usando il -lflag.


Non sono sicuro del motivo per cui questo è stato sottoposto a downgrade, funziona
Panther

Dato che *.mp4è espanso dalla shell, no ls, ciò fallirà se ci sono così tanti .mp4file nella directory che la loro lista non può essere passata lscome argomento.
David Richerby,

@Rmana Provalo in una directory contenente un file chiamato--.mp4
David Richerby,

@DavidRicherby sì, hai ragione. --risolverà il secondo caso; il primo genererà un messaggio di errore (sono necessari molti file!) e un'altra bella domanda qui. Casi angolari, ma vale la pena notare, sì.
Rmano,

1
@Rmano Senza aggiungere -qo -b, questo non tollera le nuove righe nei nomi dei file. Se corri ls -1 *.mp4dal tuo terminale senza pipe, lsvede che il suo stdout è un terminale e prende -qcome implicito, stampando ?s. Ma quel comportamento scompare quando l'output viene convogliato. ls -1 *.mp4 | wc -lsovrastima se ci sono newline. ls -1 *.mp4 | catmostra ciò che wc"vede". (Allo stesso modo, -1è implicito quando stdout non è un terminale, quindi è facoltativo.) ls -1q -- *.mp4 | wc -lFunziona quasi, ma non con zero file .mp4.
Eliah Kagan,

0

Questo dovrebbe darti l'elenco dei file con .mp4

ls /path/to/directory | grep ".mp4$"

Se combinato con wc -lti darà il conto

ls /path/to/directory | grep ".mp4$" | wc -l

se si desidera che la ricerca includa le sottodirectory

ls -lR /path/to/directory | grep ".mp4$" | wc -l

non conta
Pantera

me l'ha dato una volta usato conwc -l
Back.Slash il

usa ls senza piping per grep e abbreviare la tua risposta. È stato pubblicato almeno due volte ora.
Pantera,

@ bodhi.zazen ls /directory/*.mp4fa sì che la shell espanda il glob ed esegua qualcosa del genere ls /directory/file1.mp4 /directory/file2.mp4 ...Questo fallirà se la directory contiene più file mp4 di quanti possano essere passati come argomenti ls.
David Richerby,

@DavidRicherby - non è il mio comando ls, io uso find;)
Pantera

0

In bash, un freddo ricorso all'utilizzo di array con glob:

$ files=( *.mp4  )
$ echo ${#files[@]}
30

0
ls | grep --count \.csv$

Sostituisci (.csv con l'estensione desiderata)

Spiegazione: Penso che uno schema semplice sia recuperare l'elenco dei file e contare l'estensione con grep. \.per abbinare .e $abbinare l'estensione alla fine della riga. Funziona perché quando viene inviato l'output di ls, viene inviato un nome file per riga, che è possibile verificare eseguendo:

ls | cat

1
Nota che invece di grep --count, potresti anche usare grep -c.
Mohsin Raza,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.