Metodo 1: usa ciò che sai
Poiché sai già come eseguire il loop su un file, puoi combinare i file e quindi elaborare i file combinati. Il comando paste
unisce due file riga per riga. Inserisce una scheda tra le linee provenienti dai due file, quindi questa soluzione presuppone che non ci siano schede nei nomi dei file. (Puoi cambiare il separatore ma devi trovare un carattere che non è presente nel nome di un file.)
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 si desidera saltare le righe vuote, è necessario farlo separatamente in ciascun file, poiché paste
potrebbe corrispondere a una riga vuota di un file con una riga non vuota di un altro file. È possibile utilizzare grep
per filtrare le righe non vuote.
paste -- <(grep '[^[:space:]]' "$list1.txt") <(grep '[^[:space:]]' "list2.txt") |
while IFS=$'\t' read -r file1 file2 rest; do
…
Nota che se i due file hanno lunghezze diverse, otterrai uno spazio vuoto $file2
(indipendentemente dall'elenco terminato per primo).
Metodo 2: ciclo su due file
Puoi inserire un comando complesso come desideri nella condizione del ciclo while. Se lo metti, read file1 <&3 && read file2 <&4
il ciclo funzionerà finché entrambi i file hanno una riga da leggere, cioè fino a quando un file si esaurisce.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
Se vuoi saltare le righe vuote, è un po 'più complicato, perché devi saltare i due file in modo indipendente. Il modo più semplice è dividere il problema in due parti: saltare le righe vuote da un file ed elaborare le righe non vuote. Un metodo per saltare le righe vuote è elaborare grep
come sopra. Fai attenzione allo spazio necessario tra l' <
operatore di reindirizzamento e quello <(
che avvia una sospensione del comando.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3< <(grep '[^[:space:]]' "$list1.txt") 4< <(grep '[^[:space:]]' "list2.txt")
Un altro metodo è scrivere una funzione che si comporta come read
ma salta le righe vuote. Questa funzione può funzionare chiamando read
in un ciclo. Non deve essere una funzione, ma una funzione è l'approccio migliore, sia per organizzare il codice sia perché quel pezzo di codice deve essere chiamato due volte. Nella funzione, ${!#}
è un'istanza del costrutto bash ${!VARIABLE}
che valuta il valore della variabile il cui nome è il valore di VARIABLE
; qui la variabile è la variabile speciale #
che contiene il numero del parametro posizionale, quindi ${!#}
è l'ultimo parametro posizionale.
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
.