2012-06-11 15 views
17

En Java, si sabe con certeza que un archivo es muy pequeño, puede usar el método readBytes() para leer el contenido de una vez en lugar de leerlo línea por línea o usar el búfer.¿Cómo leer el contenido del archivo en una variable de una vez?

Sólo me preguntaba en shell script, sé que podemos hacer algo como:

while read line 
    do 
     echo $line 
     LINE = $line 
    done < "test.file" 
    echo $LINE 

Si mi test.file es como:

testline1 
testline2 
testline3 

Esto sólo me da la última línea para $LINE. $LINE contiene "testline3".

Mi pregunta es: ¿cómo puedo leer todo el archivo con varias líneas en una sola variable, así que puedo obtener $LINE="testline1\ntestline2\ntestline3"?

+1

datos (archivo gato) '= $', ¿pero Por qué querrías? ¡Solo lea el archivo cada vez que necesite el contenido! –

+1

Dos cosas que no están directamente relacionadas con su pregunta: primero, 'LINE = $ line' en realidad no funciona; el espacio alrededor del signo igual lo invalida. En segundo lugar, si está manipulando texto que desea conservar literalmente, debe establecer 'IFS' nulo para sus llamadas de lectura (de lo contrario, se numerará el espacio en blanco de cada línea) y pasar la opción' -r' a 'leer' y la opción '-E' para' echo' (de lo contrario, cualquier barra invertida en su archivo estropeará las cosas). Ver mi respuesta a continuación, por ejemplo. –

+0

@MarkReed: nunca he entendido el propósito de ''E' ya que ese es el comportamiento predeterminado de Bash para' echo'. –

Respuesta

56

Procese las líneas dentro del lazo en lugar de hacerlo después. Si realmente necesita el archivo en una variable:

var=$(<file) 
+0

¿Podría explicarnos también qué está pasando aquí? – sbhatla

+2

@sbhatla: la variable se establece en el valor de la sustitución de comando que contiene una redirección que lee el contenido del archivo. Es similar a 'var = $ (archivo cat)' pero no requiere que se genere un ejecutable externo). –

8

Como otra opción, puede construir un conjunto de líneas. Si está ejecutando fiesta de 4+, se puede utilizar la orden interna mapfile:

mapfile -t lines <test.file 

Si desea que las líneas sean de salida, así como almacenados que se podría hacer algo como esto:

mapfile -t lines < <(tee /dev/tty <test.file) 

Entonces "${lines[0]}" será la primera línea del archivo, "${lines[1]}" el segundo, y así sucesivamente. ${#lines[@]} será el número de líneas; "${lines[@]}" será la matriz completa, mientras que "${lines[*]}" serán las líneas unidas con espacios en una cadena grande.

Para versiones anteriores de fiesta, se puede construir la matriz de forma manual:

lines=() 
while IFS= read -r line 
do 
    printf '%s\n' "$line" 
    lines+=("$line") 
done < test.file 
+1

Esto sería más fácil de escribir como 'LINEAS + = (" $ línea ")', ¿no? –

+0

Sí. He aprendido un poco en 4 años, parece. Bueno saber.:) –

+0

No lo dudo por un segundo :) –

10

Otra alternativa es utilizar el buen orden interna mapfile:

mapfile < test.file 
echo "${MAPFILE[@]}" 
+2

No hay una página de manual, pero 'help mapfile' dará más información. La utilidad colocará por defecto la primera línea en la entrada 0, la segunda línea en la entrada 1, y así sucesivamente. Es probable que también desee usarlo con la opción '-t' (strip newlines). – parvus

+1

Tenga en cuenta que 'mapfile' se introdujo en bash 4, por lo que no está disponible en'/bin/bash' en OS X. Que probablemente sea el último bastión de bash 3 que probablemente se encuentre en estado salvaje, pero que probablemente no se actualice debido a problemas de licencia con Apple y la nueva GPL. –

+1

Cuando Apple actualizó desde Mac OS a Macos, incluyó bash 4.4. – DopeGhoti

Cuestiones relacionadas