Método 1: usa lo que sabes
Como ya sabe cómo recorrer un archivo, puede combinar los archivos y luego procesarlos. El comando paste
une dos archivos línea por línea. Pone una pestaña entre las líneas que provienen de los dos archivos, por lo que esta solución supone que no hay pestañas en los nombres de los archivos. (Puede cambiar el separador, pero debe encontrar un carácter que no esté presente en un nombre de archivo).
paste -- "$list1.txt" "list2.txt" |
while IFS=$'\t' read -r file1 file2 rest; do
diff -q -- "$file1" "$file2"
case $? in
0) status='same';;
1) status='different';;
*) status='ERROR';;
esac
echo "$status $file1 $file2"
done
Si desea omitir las líneas en blanco, debe hacerlo en cada archivo por separado, ya que paste
podría coincidir con una línea en blanco de un archivo con una línea no en blanco de otro archivo. Puede usar grep
para filtrar las líneas no en blanco.
paste -- <(grep '[^[:space:]]' "$list1.txt") <(grep '[^[:space:]]' "list2.txt") |
while IFS=$'\t' read -r file1 file2 rest; do
…
Tenga en cuenta que si los dos archivos tienen longitudes diferentes, obtendrá un espacio vacío $file2
(independientemente de qué lista finalizó primero).
Método 2: recorrer dos archivos
Puede poner un comando tan complejo como desee en la condición del bucle while. Si lo coloca read file1 <&3 && read file2 <&4
, el ciclo se ejecutará siempre que ambos archivos tengan una línea para leer, es decir, hasta que se agote un archivo.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
Si desea omitir las líneas en blanco, es un poco más complicado, ya que debe omitir los dos archivos de forma independiente. La manera fácil es dividir el problema en dos partes: omita las líneas en blanco de un archivo y procese las líneas que no están en blanco. Un método para omitir las líneas en blanco es procesarlo grep
como se indicó anteriormente. Tenga cuidado con el espacio necesario entre el <
operador de redireccionamiento y el <(
que inicia una suscripción de comando.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3< <(grep '[^[:space:]]' "$list1.txt") 4< <(grep '[^[:space:]]' "list2.txt")
Otro método es escribir una función que se comporte como read
pero salte las líneas en blanco. Esta función puede funcionar llamando read
a un bucle. No tiene que ser una función, pero una función es el mejor enfoque, tanto para organizar su código como porque ese código debe llamarse dos veces. En la función, ${!#}
es una instancia de la construcción bash ${!VARIABLE}
que evalúa el valor de la variable cuyo nombre es el valor de VARIABLE
; aquí la variable es la variable especial #
que contiene el número de parámetro posicional, por lo que ${!#}
es el último parámetro posicional.
function read_nonblank {
while read "$@" &&
[[ ${!#} !~ [^[:space:]] ]]
do :; done
}
while read_nonblank -u 3 -r file1 && read_nonblank -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
diff
.