我有两个文本文件,我试图同时逐行阅读。这些文件不一定具有相同数量的行,并且脚本到达任一文件末尾时应停止阅读。我想将其保持为"纯"狂欢。我发现这样做的大多数解决方案都表明了一些形式:
while read -r f1 && read -r f2 <&3; do
echo "$f1"
echo "$f2"
done < file1 3<file2
但是,如果文件的最后一行没有newline,则会失败。
如果我只读一个文件,我会做类似的事情:
while IFS='' read -r line || [[ -n "$line" ]]; do
echo "$line"
done < file1
但是,当我尝试将其扩展到以下操作时,将其扩展到读取多个文件时。
while IFS='' read -r f1 || [[ -n "$f1" ]] && read -r f2 <&3 || [[ -n "$f2" ]]; do
echo "$f1"
echo "$f2"
done < file1 3<file2
或
while IFS='' read -r f1 && read -r f2 <&3 || [[ -n "$f1" || -n "$f2" ]]; do
echo "$f1"
echo "$f2"
done < file1 3<file2
我似乎无法正确正确的逻辑,并且循环不会在不阅读最后一行的情况下终止或结束。
我可以使用:
获得所需的行为while true; do
read -r f1 <&3 || if [[ -z "$f1" ]]; then break; fi;
read -r f2 <&4 || if [[ -z "$f2" ]]; then break; fi;
echo "$f1"
echo "$f2"
done 3<file1 4<file2
但是,这似乎与普通(?(
不匹配while ... read ...; do
...
done
我看到的读物的成语。
是否有一种更好的方法可以同时读取两个可能具有不同数量的线路和未终止的线路的文件?
我读取文件的方式的潜在缺点是什么?
您可以通过将它们分组给{ }
:
&&
和||
操作员的优先级。 while { IFS= read -r f1 || [[ -n "$f1" ]]; } && { IFS= read -r f2 <&3 || [[ -n "$f2" ]]; }; do
一些注释:在这种情况下,您不能使用( )
进行分组,因为这迫使其内容在子壳中运行,并且在父壳中没有子壳中的变量read
。另外,您需要每个}
之前的;
,因此Shell可以说它不仅是最后一个命令的参数。最后,您需要 IFS=
(或等效地 IFS=''
(,因为 read
命令,因为作为命令的前缀给出的分配仅适用于该命令。