Elenca i file ordinati in base al numero di righe che contengono


32

Come posso elencare il numero di righe nei file /group/book/four/word, ordinati per numero di righe che contengono?

ls -l il comando li elenca ma non li ordina


1
Desideri i file elencati per numero di righe o elencare il numero di righe nei file o entrambi? ls -lnon fornisce il numero di righe. ls -lSordina i file per dimensione con alcune lsimplementazioni (la dimensione è il numero di byte nel contenuto).
Stéphane Chazelas,

Risposte:


34

Dovresti usare un comando come questo:

find /group/book/four/word/ -type f -exec wc -l {} + | sort -rn
  • find: cerca i file sul percorso desiderato. Se non lo si desidera ricorsivo e l' findimplementazione lo supporta, è necessario aggiungere -maxdepth 1poco prima -execdell'opzione.
  • exec: dice al comando di eseguire wc -lsu ogni file.
  • sort -rn: ordina i risultati numericamente in ordine inverso. Dal più grande al più basso.

(ciò presuppone che i nomi dei file non contengano caratteri di nuova riga).


Nota che quando viene passato più di un file (o con alcune implementazioni, più di un file che può leggere), wcverrà anche stampata una totalriga, quindi qui otterrai anche una o più righe "totali" a meno che non ci sia un solo file . È possibile reindirizzare a grep /per rimuoverli.
Stéphane Chazelas,

votato per sortcomando
Francisco,

come posso filtrare per mostrare solo il file con minimo X righe (escludi X = 0 riga per esempio)?
Matrix

11

Non ricorsiva

Probabilmente la versione più semplice se non hai bisogno di ricorsività:

wc -l /group/book/four/word/*|sort -n

wcconta le righe (opzione -l) in ogni file (ma nascosto) ( *) sotto /group/book/four/word/e sortordina |numericamente il risultato (attraverso la pipe )-n ) ).

Ricorsivo

Qualcuno ha fatto un commento a questa risposta menzionando grep -rlc, prima di sopprimerla. Infatti grepè un'ottima alternativa, soprattutto se hai bisogno di ricorsività:

grep -rc '^' /group/book/four/word/|tr ':' ' '|sort -n -k2

conterà (opzione -c) in modo ricorsivo (opzione -r) le righe corrispondenti ( grep) '^'(ovvero l'inizio delle righe) nella directory /group/book/four/word/. Quindi devi sostituire i due punti con uno spazio, ad esempio usando tr, per aiutare sort, che vuoi ordinare numericamente (opzione -n) sulla seconda colonna (opzione-k2 ).

Aggiornamento: vedi il commento di Stephane sulle possibili limitazioni e su come puoi effettivamente sbarazzartene tr.


3
grep -c .conta le righe che contengono almeno un carattere valido. Usa grep -c '^'per contare tutte le linee (conterà anche alcune lettere finali dopo l'ultima nuova riga con alcune grepimplementazioni). Si noti che non tutte le grepimplementazioni supportano -rae il comportamento varia tra quelli che lo fanno. Non è necessario tradurre :s (due punti, non punto e virgola) in spazi per sort. Basta usare -t:. Si noti che ciò presuppone che i nomi dei file non contengano :caratteri vuoti o di nuova riga.
Stéphane Chazelas,

1
Grazie per aver pubblicato la tua soluzione non ricorsiva; Non sapevo di aver wcdato un totale così utile se passi più percorsi. Accoppiare quella funzionalità con il jolly e il pipe sortè davvero pulito.
Qcom,

7

Con zsh:

lines() REPLY=$(wc -l < $REPLY)
printf '%s\n' /group/book/four/word/*(.no+lines)

Definiamo una nuova funzione di ordinamentolines che risponde con il numero di righe nel file. E usiamo il o+linesqualificatore glob che insieme a n(per ordinamento numerico), definisce come sono ordinati i risultati del glob. (. aggiunto anche per controllare solo i file normali).

Ciò non presuppone quale carattere i nomi dei file possano contenere diversi dai file nascosti (quelli che iniziano con .) sono omessi. Aggiungi il Dqualificatore glob se vuoi anche loro.


2
OP è taggato con bashsolo ...
l0b0,

7
@ l0b0 ciò non significa che anche la prossima persona che ne ha bisogno eseguirà bash.
terdon

4

Non specifichi se desideri anche i file in alcuna sottodirectory di /group/book/four/word. La findsoluzione nella risposta di jherran scenderà nelle sottodirectory. Se ciò non è desiderato, utilizzare invece la shell:

for file in ./*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Se i nomi dei tuoi file possono contenere newline, puoi usare qualcosa come:

for file in ./*; do 
    [ -f "$file" ] && 
        printf "%lu %s\0" "$(wc -l < "$file")" "$file"
done | sort -zn | tr '\0' '\n'

Infine, se si fa voglia di scendere in sottodirectory, è possibile utilizzare questo in bash4 o superiore:

shopt -s globstar
for file in ./**/*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Si noti che le versioni bashprecedenti alla 4.3 seguivano i collegamenti simbolici quando si discendeva ricorsivamente dall'albero delle directory (come zsh"o tcsh"***/* ).

Inoltre, tutte le soluzioni sopra ignoreranno i file nascosti (quelli il cui nome inizia con a ., li usano shopt -s dotglobper includerli) e includeranno anche il conteggio delle linee di collegamenti simbolici (che l' findapproccio non prevede).


Nota che altre differenze rispetto alla soluzione di jherran è che la tua considererà anche il link simbolico ai file normali ( -xtype fin GNU find o *(-.)in zsh) e ometterà i file nascosti.
Stéphane Chazelas,

@ Grazie StéphaneChazelas, chiarito. Perché l' %luin in printf? Ricordo che ciò significa decimali lunghi senza segno, è davvero necessario? Perché non trattare il numero come una stringa? Fa la differenza?
terdon

2
Se l'output del wc è vuoto (ad esempio perché il file non è leggibile), questo si espanderà 0invece della stringa vuota, il che è leggermente migliore. Alcune implementazioni di ordinamento funzionano con numeri interi senza segno, altri con segno. %lusuona come la scommessa più sicura, ma probabilmente non importa come se avessi delle 2^31linee, che comunque richiederà secoli.
Stéphane Chazelas,

1

Se vuoi installare fdun cercatore di file molto veloce scritto in Rust (dovresti installarlo, è bello averlo comunque)

fd --type=file . | xargs wc -l | sort -n

Fondamentalmente fdelenca i file, xargs passerà l'elenco dei file a wc(sta per conteggio delle parole ma passando -l lo farà contare le righe) quindi alla fine viene ordinato dal minimo numero di righe al massimo utilizzo sort -n.

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.