O objetivo do script que estou criando é comparar duas séries de arquivos. Os nomes dos arquivos são armazenados em dois arquivos separados, um caminho por linha. Minha idéia é ter dois while read
loops, um para cada lista de nomes de arquivos, mas como posso misturar os dois loops?
while read compareFile <&3; do
if [[ ! $server =~ [^[:space:]] ]] ; then #empty line exception
continue
fi
echo "Comparing file - $compareFile"
if diff "$compareFile" _(other file from loop?_) >/dev/null ; then
echo Same
else
echo Different
fi
done 3</infanass/dev/admin/filestoCompare.txt
Eu preciso ser capaz de comparar arquivos de duas listas diferentes ao mesmo tempo através de dois enquanto lê loops ... Isso é possível?
bash
shell-script
control-flow
mkrouse
fonte
fonte
diff
.diff
.Respostas:
Você não precisa de dois loops; você só precisa ler de dois arquivos em um loop.
fonte
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
paste
une 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.)Se você quiser pular linhas em branco, precisará fazê-lo em cada arquivo separadamente, pois
paste
pode corresponder uma linha em branco de um arquivo com uma linha não em branco de outro arquivo. Você pode usargrep
para filtrar as linhas que não estão em branco.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.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
grep
como acima. Cuidado com o espaço necessário entre o<
operador de redirecionamento e o<(
que inicia uma suspeita de comando.Outro método é escrever uma função que se comporte como,
read
mas pule linhas em branco. Esta função pode funcionar chamandoread
um 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 deVARIABLE
; 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.fonte
-u
opção de leituraUma abordagem seria usar em
read -ra
vez de apenasread
. Assumindo asfilestoCompare.txt
2 colunas contidas com os nomes dos arquivos em cada uma,read -ra
elas leriam as duas colunas ao mesmo tempo e as atribuiriam a uma matrizcompareFile
,. Essa matriz pode ser acessada para que o índice 0 seja o primeiro arquivo e o índice 1 seja o 2º arquivo a cada vez nowhile
loop.Exemplo
Digamos que eu tenho este arquivo:
filestoCompare.txt
e ele contém o seguinte:O comando para passar por esse arquivo seria o seguinte:
Se os 2 arquivos são realmente arquivos separados, como:
Eles podem ser unidos ao
paste
comando da seguinte maneira:Aqui está o conteúdo de list1and2:
fonte
join
eles primeiro.paste
para ingressar nos 2 arquivos? Isso levaria você a não votar?