我是否应该使用 for 循环逐行处理文本文件



所以我有两个文本文件

  • 文件1:1-40个名称
  • 文件2:1-40个名字

现在我希望程序(终端(做的是遍历每个名称,方法是在每个文件中递增 1,以便 FILE1 中的第一个名称运行 FILE2 的第一行,FILE1 中的第 20 个名称运行 FILE2 中的第 20 行。

但我不希望它运行 FILE1 的名字,然后运行 FILE2 中列出的所有名称,并一遍又一遍地重复。我应该做一个 for 循环吗?

我正在考虑做这样的事情:

for f in (cat FILE1); do 
    flirt -in $f -ref (cat FILE2); 
done

我正在使用 BASH 来做到这一点。

是的,您可以非常轻松地做到这一点,但它需要同时从两个不同的文件描述符中读取。您可以简单地将其中一个文件重定向到下一个可用的文件描述符中,并使用它来馈送您的读取循环,例如

while read f1var && read -u 3 f2var; do
    echo "f1var: $f1var -- f2var: $f2var"
done <file1.txt 3<file2.txt

它将从每个文件中逐行读取,从标准文件描述符上的file1.txt读取一行到f1var,从 fd3 上的file2.txt读取到f2var

一个简短的例子可能会有所帮助:

示例输入文件

$ cat f1.txt
a
b
c
$ cat f2.txt
d
e
f

使用示例

$ while read f1var && read -u 3 f2var; do 
echo "f1var: $f1var -- f2var: $f2var"; 
done <f1.txt 3<f2.txt
f1var: a -- f2var: d
f1var: b -- f2var: e
f1var: c -- f2var: f

使用paste作为替代

方法

paste实用程序还提供了逐行合并文件的简单替代方法,例如:

$ paste f1.txt f2.txt
a       d
b       e
c       f

在 Bash 中,您可以使用数组:

echo "Alice
> Bob
> Claire" > file-1
echo "Anton
Bärbel
Charlie" > file-2
n1=($(cat file-1))
n2=($(cat file-2))
for n in {0..2}; do echo ${n1[$n]} ${n2[$n]} ; done
Alice Anton
Bob Bärbel
Claire Charlie

熟悉 join 和 nl(数字行(不会出错,因此这里有一种不同的方法:

nl -w 1 file-1 > file1
nl -w 1 file-2 > file2 
join -1 1 -2 1 file1 file2 | sed -r 's/^[0-9]+ //'

nl 在小行号前面放了大量的空格,如果我们不告诉它 -w 1。

我们通过匹配行号来连接文件,然后使用 sed 删除行号。

粘贴当然要优雅得多。不知道这件事。

最新更新