Quería saber si hay alguna forma de leer dos archivos de entrada en un bucle anidado mientras una línea a la vez. Por ejemplo, digamos que tengo dos archivos FileA
y FileB
.
Presentar un:
[jaypal:~/Temp] cat filea
this is File A line1
this is File A line2
this is File A line3
Archivo B:
[jaypal:~/Temp] cat fileb
this is File B line1
this is File B line2
this is File B line3
Script de muestra actual:
[jaypal:~/Temp] cat read.sh
#!/bin/bash
while read lineA
do echo $lineA
while read lineB
do echo $lineB
done < fileb
done < filea
Ejecución:
[jaypal:~/Temp] ./read.sh
this is File A line1
this is File B line1
this is File B line2
this is File B line3
this is File A line2
this is File B line1
this is File B line2
this is File B line3
this is File A line3
this is File B line1
this is File B line2
this is File B line3
Problema y salida deseada:
Esto recorre completamente FileB para cada línea en FileA. Intenté continuar, romper, salir, pero ninguno de ellos está destinado a lograr el resultado que estoy buscando. Me gustaría que el script lea solo una línea del Archivo A y luego una línea del Archivo B y salga del bucle y continúe con la segunda línea del Archivo A y la segunda línea del Archivo B. Algo similar al siguiente script:
[jaypal:~/Temp] cat read1.sh
#!/bin/bash
count=1
while read lineA
do echo $lineA
lineB=`sed -n "$count"p fileb`
echo $lineB
count=`expr $count + 1`
done < filea
[jaypal:~/Temp] ./read1.sh
this is File A line1
this is File B line1
this is File A line2
this is File B line2
this is File A line3
this is File B line3
¿Es esto posible lograr con el ciclo while?
bash
shell-script
io-redirection
jaypal singh
fuente
fuente
paste -d '\n' file1 file2
Respuestas:
Si sabe con certeza que algún carácter nunca aparecerá en el primer archivo, entonces puede usar pegar.
Ejemplo de pegar usando la pestaña delimitador predeterminado:
Ejemplo de pegar usando
@
:Tenga en cuenta que es suficiente si se garantiza que el carácter no aparecerá en el primer archivo. Esto se debe a que
read
se ignoraráIFS
al completar la última variable. Entonces, incluso si@
ocurre en el segundo archivo, no se dividirá.Ejemplo de pegar usando algunas características de bash para un código posiblemente más limpio:
Características de Bash utilizadas: cadena ansi c (
$'\t'
) y sustitución de proceso (<(...)
) para evitar el ciclo while en un problema de subshell .Si no puede estar seguro de que algún carácter nunca aparecerá en ambos archivos, puede usar descriptores de archivo .
No probado mucho. Podría romperse en líneas vacías.
Los descriptores de archivo número 0, 1 y 2 ya se utilizan para stdin, stdout y stderr, respectivamente. Los descriptores de archivos de 3 en adelante son (generalmente) gratuitos. El manual de bash advierte sobre el uso de descriptores de archivo superiores a 9, porque se "usan internamente".
Tenga en cuenta que los descriptores de archivos abiertos se heredan de las funciones de shell y los programas externos. Las funciones y los programas que heredan un descriptor de archivo abierto pueden leer (y escribir) en el descriptor de archivo. Debe tener cuidado de cerrar todos los descriptores de archivos que no son necesarios antes de llamar a una función o programa externo.
Aquí está el mismo programa que el anterior con el trabajo real (la impresión) separado del meta trabajo (lectura línea por línea de dos archivos en paralelo).
Ahora pretendemos que no tenemos control sobre el código de trabajo y ese código, por cualquier razón, intenta leer del descriptor de archivo 3.
Aquí hay un ejemplo de salida. Tenga en cuenta que la segunda línea del primer archivo es "robada" del bucle.
A continuación, le indicamos cómo debe cerrar los descriptores de archivo antes de llamar a un código externo (o cualquier código para el caso).
fuente
Abra los dos archivos en diferentes descriptores de archivo . Redirija la entrada del
read
incorporado al descriptor al que está conectado el archivo que desea. En bash / ksh / zsh, puedes escribir enread -u 3
lugar deread <&3
.Este fragmento se detiene cuando se procesa el archivo más corto. Consulte Lectura de dos archivos en un bucle IFS while: ¿hay alguna forma de obtener un resultado de diferencia cero en este caso? si desea seguir procesando hasta el final de ambos archivos.
Consulte también ¿ Cuándo utilizaría un descriptor de archivo adicional? para obtener información adicional sobre los descriptores de archivos y por qué se usa `while IFS = read` tan a menudo, en lugar de` IFS =; mientras lee..`? para una explicación de
IFS= read -r
.fuente
Sé que desea un script de shell, pero es posible que desee echar un vistazo al
paste
comando.fuente
paste
También es genial.Prueba el siguiente comando:
fuente
Alternativamente, supongo que podría sorber el archivo en una variable de matriz uniendo cada línea del archivo en la matriz [line_of_file_index] usando el comando maphile de bash. Sin embargo, no estoy seguro de si es solo para Bash3 superior o Bash4.
http://wiki.bash-hackers.org/commands/builtin/mapfile
fuente