obtener solo el número entero de wc en bash

115

¿Hay alguna forma de obtener el entero que devuelve wc en bash?

Básicamente, quiero escribir los números de línea y el recuento de palabras en la pantalla después del nombre del archivo.

output: filename linecount wordcount Esto es lo que tengo hasta ahora:

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

Jordán
fuente

Respuestas:

57

Puede usar el cutcomando para obtener solo la primera palabra de wcla salida de (que es la línea o el recuento de palabras):

lines=`wc -l $f | cut -f1 -d' '`
words=`wc -w $f | cut -f1 -d' '`
casablanca
fuente
5
Ejecutar wc dos veces para el mismo archivo es ineficaz.
gawi
3
Es cierto, por eso creo que la respuesta de James Broadhead es mucho mejor. No pude cuttrabajar en la salida completa de wc $fporque la cantidad de espacios entre campos varía.
Casablanca
1
@casablanca Puedes reducir el número de espacios usando 'tr -s'. He enumerado más soluciones portátiles para esta pregunta en mi respuesta a continuación.
rublo
Dado que en esta respuesta estamos asignando a una variable, podríamos matar los espacios con
cycollins
88

La respuesta más simple de todos:

wc < filename 
BananaNeil
fuente
5
Pero no produce el resultado deseado.
Dave Newton
seguro que lo hace, simplemente pase los parámetros adecuados que de todos modos haría. por ejemplo, si lo hace wc -c < file name, le dará solo el número entero de bytes y nada más.
BananaNeil
13
Mi punto fue que si vas a responder una pregunta (de 1.5 años), también podrías poner toda la información en la respuesta, eso es todo :)
Dave Newton
Vaya, solo vuelva a leer la pregunta .. #fallo, estaba investigando cómo obtener solo los números enteros, y estaba usando información de una de las respuestas, cuando descubrí una mejor respuesta, y luego decidí publicar sobre ella. lo siento ..
BananaNeil
3
Has respondido a Google, eso es lo que cuenta. :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
82

Sólo:

wc -l < file_name

hará el trabajo. Pero esta salida incluye espacios en blanco con prefijo ya que wcalinea a la derecha el número.

sten
fuente
3
Para obtener solo el recuento de líneas sin espacios en blanco: wc -l < foo.txt | xargsref - stackoverflow.com/a/12973694/149428
Taylor Edmiston
1
Entonces, mientras el comando produce una respuesta con espacios iniciales, el interrogador estaba asignando a una variable y eso elimina los espacios iniciales automáticamente (al menos esa fue mi experiencia en el bash OSX anterior). En otras palabras, lines=`wc -l < $f`da como resultado una "línea" variable cuyo valor no tiene espacios iniciales.
cicolinas
¿Qué pasa si estoy conectando con find? Recibo un error: find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -lfunciona bien pero imprime todos los archivos. Si lo uso find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -l <, obtengo un error. parse error near '\n'
Nuno Gonçalves
55
wc $file | awk {'print "$4" "$2" "$1"'}

Ajuste según sea necesario para su diseño.

También es más agradable usar lógica positiva ("es un archivo") sobre negativa ("no es un directorio")

[ -f $file ] && wc $file | awk {'print "$4" "$2" "$1"'}
James Broadhead
fuente
1
En mi Windows en Cmder (bash 4.4.12) esto funciona: wc $file | awk '{print $4" "$2" "$1}'- apóstrofos fuera de {}.
Grzegorz Gierlik
36

A veces, wc genera salidas en diferentes formatos en diferentes plataformas. Por ejemplo:

En OS X:

$ echo aa | wc -l

         1

En Centos:

$ echo aa | wc -l

1

Por lo tanto, es posible que usar solo cortar no recupere el número. En su lugar, intente tr para eliminar los espacios:

$ echo aa | wc -l | tr -d ' '
Tahsin Turkoz
fuente
23

Las respuestas aceptadas / populares no funcionan en OSX.

Cualquiera de los siguientes debe ser portátil en bsd y linux.

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

O

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

O

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

Si redirige el nombre del archivo wc, omite el nombre del archivo en la salida.

Intento:

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

o

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

En lugar de usar forpara iterar sobre la salida de ls, haga esto:

for f in *

que funcionará si hay nombres de archivo que incluyen espacios.

Si no puede usar globbing, debe canalizar en un while readbucle:

find ... | while read -r f

o utilizar sustitución de procesos

while read -r f
do
    something
done < <(find ...)
Pausado hasta nuevo aviso.
fuente
Te voté a favor de todos modos, pero no necesitas redirigir el nombre del archivo. Captúrelo como un campo adicional. read lines words characters filename <<< $(wc "$f")Ah, y si solía endurecerse * contra los espacios, también desea comillas dobles la var cuando la use.
Bruno Bronosky
Usar una variable adicional es de hecho otra forma de hacerlo, pero si no va a usar la variable (tal vez ya tenga el nombre del archivo en una variable, $fen este caso), no es necesario. Además, el OP preguntó cómo obtener solo el número entero. Tiene razón al citar una variable, pero no mostré el uso de la variable, así que omití mencionar ese punto. El for f in *formulario casi siempre debe usarse en lugar de usar la salida de ls, como sabe.
Pausado hasta nuevo aviso.
Estoy completamente de acuerdo con el lspunto. Eso te dará un premio. partmaps.org/era/unix/award.html#ls
Bruno Bronosky
Si no desea el nombre del archivo, puede hacer esto:read lines words characters _ <<< $(wc "$f")
@EvanTeitelman: Como se discutió en un par de comentarios sobre el suyo. $_es solo una variable diferente.
Pausado hasta nuevo aviso.
3

Si el archivo es pequeño, puede darse el lujo de llamar wcdos veces y usar algo como lo siguiente, que evita la canalización hacia un proceso adicional:

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

El $((...))es la expansión aritmética de bash. Elimina cualquier espacio en blanco de la salida de wcen este caso.

Esta solución tiene más sentido si necesita ya sea la lineatura o el recuento de palabras.

Walter Tross
fuente
2

¿Qué tal con sed?

wc -l /path/to/file.ext | sed 's/ *\([0-9]* \).*/\1/'
mgold
fuente
1
typeset -i a=$(wc -l fileName.dat  | xargs echo | cut -d' ' -f1)
GeorgesMakarios
fuente
1

Pruebe esto para obtener un resultado numérico:
nlines = $ (wc -l <$ myfile)

Paulonki
fuente
0

Prueba esto:

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

Crea un recuento de líneas y un recuento de palabras (LINE y WC), y los incrementa con los valores extraídos de wc (usando $ 1 para el valor de la primera columna y $ 2 para la segunda) y finalmente imprime los resultados.

Aif
fuente
0

"Básicamente, quiero escribir los números de línea y el recuento de palabras en la pantalla después del nombre del archivo".

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

Salidas: myfile.txt líneas: 10 palabras: 20 bytes: 120

usuario8155253
fuente
0
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"
Pedro Reis
fuente
Si está utilizando de perltodos modos, también podría hacer el recuento de palabras en Perl. Un enfoque más económico sería canalizar atr -d '[:space:]'
tripleee