2012-06-07 6 views

Respuesta

8

El comando read lee líneas enteras por defecto. Entonces la solución probablemente sea leer toda la línea y luego dividirla en espacios en blanco con, p. Ej. for:

while read line; do 
    for word in $line; do 
     echo "word = '$word'" 
    done 
done 
+0

dónde debería puede el nombre de mi archivo en el código anterior? – Admia

+0

@Admia Recuerde que 'read' lee de la entrada estándar. La "mejor" manera (IMO) para resolverlo es poner el código en una función. Y dado que las funciones se pueden llamar como cualquier otro comando, también se puede usar con la redirección. Entonces, puedes hacerlo, p. 'function_with_read_loop

+0

Si su línea contiene '*' como un elemento independiente, obtendrá una lista de nombres de archivos en el directorio actual de 'for word in $ line'. (Además, 'leer' sin' -r' generará literales de barra invertida). –

14

La manera de hacer esto con la entrada estándar es pasando la opción -a para leer:

read -a words 
echo "${words[@]}" 

Esto permitirá la lectura de toda su línea en una variable de matriz indexada, en este caso llamado palabras. A continuación, puede realizar cualquier operación de matriz que desee en palabras con shell parameter expansions.

Para las operaciones orientadas a archivos, las versiones actuales de Bash también admiten el archivo de mapa built-in. Por ejemplo:

mapfile < /etc/passwd 
echo ${MAPFILE[0]} 

De cualquier forma, los arreglos son el camino a seguir. Vale la pena su tiempo para familiarizarse con Bash array syntax para aprovechar al máximo esta función.

6

Normalmente, debe leer desde un archivo utilizando un bucle while read -r line. Para hacer esto y analizar las palabras en las líneas, es necesario anidar un bucle for dentro del bucle while.

Aquí es una técnica que funciona sin necesidad de bucles anidados:

for word in $(<inputfile) 
do 
    echo "$word" 
done 
+0

No diría que la división de cuerdas es "ordinariamente" correcta. Si tiene un '*' en su archivo, obtendrá una lista de nombres en el directorio actual en su salida. –

+0

@CharlesDuffy: Ese problema también afecta la respuesta aceptada (la técnica descrita en mi segunda oración).La técnica en mi fragmento de código falla de la misma manera. –

3

En el contexto dado, cuando se conoce el número de palabras:

while read -r word1 word2 _; do 
    echo "Read a line with word1 of $word1 and word2 of $word2" 
done 

Si desea leer cada línea en una matriz, read -a pondrá la primera palabra en el elemento 0 de su matriz, la segunda en el elemento 1, etc.:

while read -r -a words; do 
    echo "First word is ${words[0]}; second word is ${words[1]}" 
    declare -p words # print the whole array 
done 
0

me encontré con esta pregunta y las respuestas propuestas, pero no ve mencionado esta solución possibile simple:

for word in `cat inputfile` 
do 
    echo $word 
done 
+0

Esto no está en la lista por una buena razón: es extremadamente defectuoso. Si su archivo de entrada tiene un '*', obtendrá una lista de archivos en el directorio actual en su salida, y porque el argumento para 'echo' no está entre comillas, si uno de sus nombres de archivos se divide en una conjunto de palabras que contiene un glob, ese glob * también * será expandido. Ver también [Por qué no lee líneas con 'for'] (http://mywiki.wooledge.org/DontReadLinesWithFor). –

Cuestiones relacionadas