Método 1: use o que você sabe
Como você já sabe fazer um loop sobre um arquivo, você pode combinar os arquivos e depois processá-los. O comando pasteune dois arquivos linha por linha. Ele coloca uma guia entre as linhas provenientes dos dois arquivos, portanto, esta solução assume que não há guias nos nomes dos arquivos. (Você pode alterar o separador, mas precisa encontrar um caractere que não esteja presente no nome de um arquivo.)
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
Se você quiser pular linhas em branco, precisará fazê-lo em cada arquivo separadamente, pois pastepode corresponder uma linha em branco de um arquivo com uma linha não em branco de outro arquivo. Você pode usar greppara filtrar as linhas que não estão em branco.
paste -- <(grep '[^[:space:]]' "$list1.txt") <(grep '[^[:space:]]' "list2.txt") |
while IFS=$'\t' read -r file1 file2 rest; do
…
Observe que, se os dois arquivos tiverem comprimentos diferentes, você ficará vazio $file2(independentemente da lista que terminou primeiro).
Método 2: loop sobre dois arquivos
Você pode colocar um comando tão complexo quanto desejar na condição do loop while. Se você colocar read file1 <&3 && read file2 <&4, o loop será executado enquanto os dois arquivos tiverem uma linha para ler, ou seja, até que um arquivo se esgote.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
Se você quiser pular linhas em branco, é um pouco mais complicado, porque é necessário pular os dois arquivos de forma independente. A maneira mais fácil é dividir o problema em duas partes: pule as linhas em branco de um arquivo e processe as linhas que não estiverem em branco. Um método para ignorar as linhas em branco é processar grepcomo acima. Cuidado com o espaço necessário entre o <operador de redirecionamento e o <(que inicia uma suspeita 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")
Outro método é escrever uma função que se comporte como, readmas pule linhas em branco. Esta função pode funcionar chamando readum loop. Não precisa ser uma função, mas uma função é a melhor abordagem, para organizar seu código e porque esse trecho de código precisa ser chamado duas vezes. Na função, ${!#}é uma instância do construto bash ${!VARIABLE}que avalia o valor da variável cujo nome é o valor de VARIABLE; aqui a variável é a variável especial #que contém o número de parâmetro posicional, assim ${!#}como o ú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.