ottieni solo il numero intero da wc in bash


115

C'è un modo per ottenere il numero intero restituito da wc in bash?

Fondamentalmente voglio scrivere i numeri di riga e il conteggio delle parole sullo schermo dopo il nome del file.

output: filename linecount wordcount Ecco cosa ho finora:

files=`ls`
for f in $files;
do
        if [ ! -d $f ] #only print out information about files !directories
        then
                # some way of getting the wc integers into shell variables and then printing them
                echo "$f $lines $ words"
        fi
done

Risposte:


57

Puoi utilizzare il cutcomando per ottenere solo la prima parola wcdell'output di (che è il conteggio delle righe o delle parole):

lines=`wc -l $f | cut -f1 -d' '`
words=`wc -w $f | cut -f1 -d' '`

5
L'esecuzione di wc due volte per lo stesso file è inefficiente.
gawi

3
È vero, ecco perché penso che la risposta di James Broadhead sia molto migliore. Non sono riuscito cuta lavorare sull'output completo di wc $fperché il numero di spazi tra i campi varia.
casablanca

1
@casablanca Puoi comprimere il numero di spazi usando "tr -s". Ho elencato più soluzioni portatili a questa domanda nella mia risposta di seguito.
rublo

Poiché in questa risposta stiamo assegnando a una variabile, potremmo uccidere gli spazi con
cycollins

88

La risposta più semplice di sempre:

wc < filename 

5
Ma non produce l'output desiderato.
Dave Newton,

certo che lo fa, devi solo passare i parametri corretti che faresti comunque. ad esempio, se lo fai wc -c < file name, ti darà solo il numero intero di byte e nient'altro.
BananaNeil

13
Il punto era che se hai intenzione di rispondere a una domanda (vecchia di 1,5 anni)) potresti anche inserire tutte le informazioni nella risposta, questo è tutto :)
Dave Newton,

whoops, rileggi la domanda .. #fail, stavo cercando come ottenere solo i numeri interi, e stavo usando le informazioni da una delle risposte, quando ho scoperto una risposta migliore, e poi ho deciso di postare a riguardo. scusa ..
BananaNeil

3
Hai risposto a Google, questo è ciò che conta. :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

82

Appena:

wc -l < file_name

farà il lavoro. Ma questo output include spazi bianchi prefissati in quanto wcallinea a destra il numero.


3
Per ottenere solo il conteggio delle righe senza spazi bianchi: wc -l < foo.txt | xargsrif - stackoverflow.com/a/12973694/149428
Taylor Edmiston

1
Quindi, mentre il comando produce una risposta con spazi iniziali, l'interrogante stava assegnando a una variabile e questo rilascia automaticamente gli spazi iniziali (almeno questa era la mia esperienza sul vecchio OSX bash). In altre parole, lines=`wc -l < $f`risulta in una variabile "linea" il cui valore non ha spazi iniziali.
cycollins

E se sto parlando con find? Ottengo un errore: find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -lfunziona bene ma stampa tutti i file. Se uso find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -l <ottengo un errore. parse error near '\n'
Nuno Gonçalves,

55
wc $file | awk {'print "$4" "$2" "$1"'}

Regola come necessario per il tuo layout.

È anche più bello usare la logica positiva ("è un file") rispetto a quella negativa ("non una directory")

[ -f $file ] && wc $file | awk {'print "$4" "$2" "$1"'}

1
Sul mio Windows in Cmder (bash 4.4.12) funziona: wc $file | awk '{print $4" "$2" "$1}'- apostrofi al di fuori di {}.
Grzegorz Gierlik

36

A volte wc produce in diversi formati su piattaforme diverse. Per esempio:

In OS X:

$ echo aa | wc -l

         1

In Centos:

$ echo aa | wc -l

1

Quindi, utilizzando solo il taglio potrebbe non recuperare il numero. Prova invece tr per eliminare i caratteri spazio:

$ echo aa | wc -l | tr -d ' '

23

Le risposte accettate / popolari non funzionano su OSX.

Ognuno dei seguenti dovrebbe essere portabile su bsd e linux.

wc -l < "$f" | tr -d ' '

O

wc -l "$f" | tr -s ' ' | cut -d ' ' -f 2

O

wc -l "$f" | awk '{print $1}'

11

Se reindirizzi il nome del file in wcesso, il nome del file viene omesso in uscita.

bash:

read lines words characters <<< $(wc < filename)

o

read lines words characters <<EOF
$(wc < filename)
EOF

Invece di usare forper iterare sull'output di ls, fai questo:

for f in *

che funzionerà se ci sono nomi di file che includono spazi.

Se non puoi usare il globbing, dovresti inserire un while readloop:

find ... | while read -r f

o utilizzare la sostituzione del processo

while read -r f
do
    something
done < <(find ...)

Ti ho comunque votato positivamente, ma non è necessario reindirizzare il nome del file. Basta catturarlo come campo aggiuntivo. read lines words characters filename <<< $(wc "$f")Oh, e se hai usato * per essere indurito contro gli spazi, vuoi anche citare due volte la var quando lo usi.
Bruno Bronosky

L'uso di una variabile aggiuntiva è davvero un altro modo per farlo, ma se non utilizzerai la variabile (forse hai già il nome del file in una variabile - $fin questo caso), non è necessario. Inoltre, l'OP ha chiesto come ottenere solo il numero intero. Hai ragione riguardo alla citazione di una variabile, ma non ho mostrato l'uso della variabile, quindi ho omesso di menzionare quel punto. Il for f in *modulo dovrebbe quasi sempre essere usato invece di usare l'output di ls, come sai.
In pausa fino a nuovo avviso.

Sono completamente d'accordo sul lspunto. Questo ti farà ottenere un premio. partmaps.org/era/unix/award.html#ls
Bruno Bronosky

Se non vuoi il nome del file, puoi farlo:read lines words characters _ <<< $(wc "$f")

@EvanTeitelman: come discusso in un paio di commenti sopra il tuo. $_è solo una variabile diversa.
In pausa fino a nuovo avviso.

3

Se il file è piccolo, puoi permetterti di chiamare wcdue volte e utilizzare qualcosa di simile al seguente, che evita il piping in un processo aggiuntivo:

lines=$((`wc -l "$f"`))
words=$((`wc -w "$f"`))

Il $((...))è l'espansione aritmetica di bash. In wcquesto caso, rimuove qualsiasi spazio bianco dall'output di .

Questa soluzione ha più senso se è necessario sia il LineCount o il numero di parole.


2

Che ne dici di sed?

wc -l /path/to/file.ext | sed 's/ *\([0-9]* \).*/\1/'


1

Prova questo per il risultato numerico:
nlines = $ (wc -l <$ myfile)


0

Prova questo:

wc `ls` | awk '{ LINE += $1; WC += $2 } END { print "lines: " LINE  " words: " WC }'

Crea un conteggio delle righe e un conteggio delle parole (LINE e WC) e li aumenta con i valori estratti da wc (utilizzando $ 1 per il valore della prima colonna e $ 2 per la seconda) e infine stampa i risultati.


0

"Fondamentalmente voglio scrivere i numeri di riga e il conteggio delle parole sullo schermo dopo il nome del file."

answer=(`wc $f`)
echo -e"${answer[3]}
lines:  ${answer[0]}
words:  ${answer[1]}
bytes:  ${answer[2]}"

Uscite: myfile.txt righe: 10 parole: 20 byte: 120


0
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"

Se stai usando perlcomunque, potresti anche fare il conteggio delle parole in Perl. Un approccio più economico sarebbe di tubotr -d '[:space:]'
tripleee
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.