una - que es un script en bash
resultados de wc como variables (7)
Me gustaría usar las líneas que vienen de ''wc'' como variables. Por ejemplo:
echo ''foo bar'' > file.txt
echo ''blah blah blah'' >> file.txt
wc file.txt
2 5 23 file.txt
Me gustaría tener algo como $lines
, $words
y $characters
asociados a los valores 2
, 5
y 23
. ¿Cómo puedo hacer eso en bash?
En puro bash: (no awk)
a=($(wc file.txt))
lines=${a[0]}
words=${a[1]}
chars=${a[2]}
Esto funciona mediante el uso de matrices de bash. a=(1 2 3)
crea una matriz con los elementos 1, 2 y 3. Podemos acceder a elementos separados con la sintaxis ${a[indice]}
.
Alternativa: (basada en solución gonvaled)
read lines words chars <<< $(wc x)
O en sh:
a=$(wc file.txt)
lines=$(echo $a|cut -d'' '' -f1)
words=$(echo $a|cut -d'' '' -f2)
chars=$(echo $a|cut -d'' '' -f3)
Hay otras soluciones, pero una simple que generalmente utilizo es poner la salida de wc
en un archivo temporal, y luego leer desde allí:
wc file.txt > xxx
read lines words characters filename < xxx
echo "lines=$lines words=$words characters=$characters filename=$filename"
lines=2 words=5 characters=23 filename=file.txt
La ventaja de este método es que no necesita crear varios procesos awk
, uno para cada variable. La desventaja es que necesita un archivo temporal, que debe eliminar después.
Ten cuidado: esto no funciona:
wc file.txt | read lines words characters filename
El problema es que las tuberías para read
crean otro proceso, y las variables se actualizan allí, por lo que no son accesibles en el shell de llamada.
Editar: añadiendo solución por arnaud576875:
read lines words chars filename <<< $(wc x)
Funciona sin escribir en un archivo (y no tiene problema de tubería). Es bash específico.
Del manual de bash:
Here Strings
A variant of here documents, the format is:
<<<word
The word is expanded and supplied to the command on its standard input.
La clave es el bit "se expande la palabra".
Puede asignar salida a una variable abriendo un sub shell:
$ x=$(wc some-file)
$ echo $x
1 6 60 some-file
Ahora, para obtener las variables separadas, la opción más simple es usar awk
:
$ x=$(wc some-file | awk ''{print $1}'')
$ echo $x
1
Quería almacenar el número de archivos csv en una variable. Lo siguiente me funcionó:
CSV_COUNT=$(ls ./pathToSubdirectory | grep ".csv" | wc -l | xargs)
- xargs elimina el espacio en blanco del comando wc
- Ejecuté este script de bash no en la misma carpeta que los archivos csv. Por lo tanto, el pathToSubdirectory
Solo para agregar otra variante -
set -- `wc file.txt`
chars=$1
words=$2
lines=$3
Esto obviamente obstruye $*
y variables relacionadas. A diferencia de algunas de las otras soluciones aquí, es portátil a otras carcasas Bourne.
declare -a result
result=( $(wc < file.txt) )
lines=${result[0]}
words=${result[1]}
characters=${result[2]}
echo "Lines: $lines, Words: $words, Characters: $characters"
lines=`wc file.txt | awk ''{print $1}''`
words=`wc file.txt | awk ''{print $2}''`
...
También puedes almacenar el resultado de wc
algún lugar primero ... y luego analizarlo ... si eres exigente con el rendimiento :)