Primeiro, Não leia as linhas com , pois há vários problemas inevitáveis com a leitura de linhas por meio da divisão de palavras.
Assumindo arquivos de tamanho igual, ou se você quiser apenas fazer um loop até que o menor de dois arquivos seja lido, uma solução simples é possível.
while read -r x && read -r y <&3; do
...
done <file1 3<file2
Colocar uma solução mais geral é difícil porque read
retorna falso e várias outras razões. Este exemplo pode ler um número arbitrário de fluxos e retornar após a entrada mais curta ou mais longa.
#!/usr/bin/env bash
# Open the given files and assign the resulting FDs to arrName.
# openFDs arrname file1 [file2 ...]
openFDs() {
local x y i arr=$1
[[ -v $arr ]] || return 1
shift
for x; do
{ exec {y}<"$x"; } 2>/dev/null || return 1
printf -v "${arr}[i++]" %d "$y"
done
}
# closeFDs FD1 [FD2 ...]
closeFDs() {
local x
for x; do
exec {x}<&-
done
}
# Read one line from each of the given FDs and assign the output to arrName.
# If the first argument is -l, returns false only when all FDs reach EOF.
# readN [ -l ] arrName FD1 [FD2 ...]
readN() {
if [[ $1 == -l ]]; then
local longest
shift
else
local longest=
fi
local i x y status arr=$1
[[ -v $arr ]] || return 1
shift
for x; do
if IFS= read -ru "$x" "${arr}[i]" || { unset -v "${arr}[i]"; [[ ${longest+_} ]] && return 1; }; then
status=0
fi
((i++))
done
return ${status:-1}
}
# readLines file1 [file2 ...]
readLines() {
local -a fds lines
trap 'closeFDs "${fds[@]}"' RETURN
openFDs fds "$@" || return 1
while readN -l lines "${fds[@]}"; do
printf '%-1s ' "${lines[@]}"
echo
done
}
{
readLines /dev/fd/{3..6} || { echo 'error occured' >&2; exit 1; }
} <<<$'a\nb\nc\nd' 3<&0 <<<$'1\n2\n3\n4\n5' 4<&0 <<<$'x\ny\nz' 5<&0 <<<$'7\n8\n9\n10\n11\n12' 6<&0
# vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh nowrap et:
Então, dependendo se readN
recebe -l
, a saída é
a 1 x 7
b 2 y 8
c 3 z 9
d 4 10
5 11
12
ou
a 1 x 7
b 2 y 8
c 3 z 9
Ter que ler vários fluxos em um loop sem salvar tudo em vários arrays não é tão comum. Se você quiser apenas ler arrays, deve dar uma olhada em mapfile
.