Come ottenere "wc -l" per stampare solo il numero di righe senza nome file?


155
wc -l file.txt

genera il numero di righe e il nome del file.

Mi serve solo il numero stesso (non il nome del file).

posso farlo

 wc -l file.txt | awk '{print $1}'

Ma forse c'è un modo migliore?


13
wc -l < file.txtfa il lavoro in modo preciso e conciso.
Jonathan Leffler,


3
Questa è una domanda che ho cercato due volte ora. Questo comportamento del wc è poco intuitivo e anti-paradigmatico per una normale terseness. Quella terseness è lì per una ragione, perché esattamente non vuoi aggirare tutti i tipi di ridondanza soffice. Dopo tutto, conosco il nome del file, no? Quello che voglio è il conteggio delle righe.
Peter - Ripristina Monica il

Risposte:


217

Prova in questo modo:

wc -l < file.txt

5
In AIX, ksh, questo avrà sempre uno spazio che precede il numero. Dobbiamo usare | awk '{print $ 1}' o un taglio, per tagliare gli spazi. Un altro modo di tagliare sarebbe racchiuderlo in un'eco.
Rao,

@rao è corretto, questo aggiungerà uno spazio prima del numero. La mia soluzione risolve questo problema ed è più semplice di awk o cut.
Desi Cochrane,

@rao Non c'è spazio con bash. Da dove viene lo spazio in ksh? wc -lnon dovrebbe emetterne uno, e perché ksh dovrebbe anteporre l'output standard di un programma con uno spazio?
Peter - Ripristina Monica il

Sebbene questa sia la soluzione corretta (ed è abbastanza facile che non sia mai stata modificata), probabilmente è più lenta e non intuitiva. Per prima cosa, mi aspetto qualcosa di simile 4711 [stdin]all'output.
Peter - Ripristina Monica il

Prendi anche in considerazione l'associazione printf "%'d", che si occupa dello spazio e stampa in modo corretto grandi numeri.
Leo

21
cat file.txt | wc -l

Secondo la pagina man (per la versione BSD, non ho una versione GNU da controllare):

Se non viene specificato alcun file, viene utilizzato l'input standard e non viene visualizzato alcun nome file. Il prompt accetterà l'input fino alla ricezione di EOF o [^ D] nella maggior parte degli ambienti.


3
Non mi piace il gatto - la concatenazione richiede molto tempo.
PoGibas,

9
wc -l < file.txtha lo stesso effetto.
pjmorse,

@utente: testalo. Di gran lunga la parte più lenta leggerà il file dal disco.
sarnold,

11
@ user1286528 quindi utilizzare wc -l < file.txtper evitare l'uso inutile di cat. Anche se sei assolutamente pazzo se pensi che ciò stia consumando tempo notevole.
Hobbs

12

Per fare questo senza lo spazio iniziale, perché no:

wc -l < file.txt | bc

Ottengo errori di sintassi con questo (Ubuntu 14.04). Penso che ci sia un problema con il nome file.
MERose,

Su un RHEL 6.7 genera errori: $ wc -l file.csv | bc (standard_in) 1: errore di sintassi (standard_in) 1: carattere illegale: N (standard_in) 1: errore di sintassi (standard_in) 1: errore di sintassi
Rodrigo Hjort,

3
Ottengo anche un errore di analisi, ma puoi combinarlo con l'altra risposta da utilizzare wc -l < file.txtper correggere l'errore di analisi e rimuovere lo spazio:wc -l < file.txt | bc
jangosteve

11

Che ne dite di

wc -l file.txt | cut -d' ' -f1

cioè reindirizza l'output di wcin cut(dove i delimitatori sono spazi e seleziona solo il primo campo)


4
questo non è meglio di quanto wc -l file.txt | awk '{print $1}'provato dall'OP.
doubleDown

1
Più veloce del wc -l < file.txtmetodo. Ma deve essere utilizzato | cut -d' ' -f2su BSD, purché il wccomando restituisca uno spazio iniziale, ad esempio: "34068289 file.txt" anziché "34068289 file.txt".
Sopalajo de Arrierez,

@doubleDown bene, usare awk è come usare una macchina CNC per tagliare una tavola anziché una sega. Usa una sega per segare.
Peter - Ripristina Monica il

5

Confronto di tecniche

Ho avuto un problema simile nel tentativo di ottenere un conteggio dei personaggi senza lo spazio bianco iniziale fornito da wc, che mi ha portato a questa pagina. Dopo aver provato le risposte qui, i seguenti sono i risultati dei miei test personali su Mac (BSD Bash). Ancora una volta, questo è per il conteggio dei personaggi; per il conteggio delle righe che faresti wc -l. echo -nomette l'interruzione della riga finale.

FOO="bar"
echo -n "$FOO" | wc -c                          # "       3"    (x)
echo -n "$FOO" | wc -c | bc                     # "3"           (√)
echo -n "$FOO" | wc -c | tr -d ' '              # "3"           (√)
echo -n "$FOO" | wc -c | awk '{print $1}'       # "3"           (√)
echo -n "$FOO" | wc -c | cut -d ' ' -f1         # "" for -f < 8 (x)
echo -n "$FOO" | wc -c | cut -d ' ' -f8         # "3"           (√)
echo -n "$FOO" | wc -c | perl -pe 's/^\s+//'    # "3"           (√)
echo -n "$FOO" | wc -c | grep -ch '^'           # "1"           (x)
echo $( printf '%s' "$FOO" | wc -c )            # "3"           (√)

Non mi affiderei al cut -f*metodo in generale poiché richiede che tu conosca il numero esatto di spazi iniziali che può avere un determinato output. E grepquello funziona per contare le linee, ma non i caratteri.

bcè il più conciso awke perlsembra un po 'eccessivo, ma dovrebbero essere tutti relativamente veloci e portatili.

Si noti inoltre che alcuni di questi possono essere adattati per tagliare anche gli spazi bianchi circostanti dalle stringhe generali (insieme a echo `echo $FOO`un altro trucco accurato).


1
echo $(printf '%s' "$FOO" | wc -c)è una delle rare occasioni in cui echocon un comando la sottoscrizione non è inutile.
triplo

@tripleee Whoa ... in base al tuo codice, echo `echo $FOO`;agisce anche come un comando String.trim () su una variabile! È incredibilmente utile. Aggiungerò anche la tua linea alla mia risposta.
Beejor,



4

Che ne dite di

grep -ch "^" file.txt

3
Bello. L'uso molto originale / creativo grepma verificandolo risulta (non sorprende) essere da 2 a 6 volte più lento del wcmetodo più semplice / diretto nei miei test.
Ari

3

Ovviamente, ci sono molte soluzioni a questo. Eccone un altro però:

wc -l somefile | tr -d "[:alpha:][:blank:][:punct:]"

Questo produce solo il numero di righe, ma \nè presente il carattere di nuova riga finale ( ), se non lo si desidera, sostituirlo [:blank:]con [:space:].


Questo ha il problema quando il nome del file contiene un numero. Ad esempio per il file test9con 1 riga, l'output sarà 19.
Raphael Ahrens

1

Il modo migliore sarebbe innanzitutto trovare tutti i file nella directory, quindi utilizzare AWK NR (Variabile numero di record)

sotto è il comando:

find <directory path>  -type f | awk  'END{print NR}'

esempio : - find /tmp/ -type f | awk 'END{print NR}'


0

Questo funziona per me usando il normale wc -le sedper eliminare qualsiasi carattere che non sia un numero.

wc -l big_file.log | sed -E "s/([a-z\-\_\.]|[[:space:]]*)//g"

# 9249133
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.