【问题标题】:Should I use a for loop to process text files line by line?我应该使用 for 循环逐行处理文本文件吗?
【发布时间】:2018-02-04 01:59:46
【问题描述】:

所以我有两个文本文件

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

现在我想让程序做的(终端)是遍历每个名​​称,通过在每个文件中递增 1 以便 FILE1 的第一个名称运行 FILE2 的第一行,而 FILE1 的第 20 个名称运行第 20 个来自 FILE2 的行。

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

我正在考虑做类似的事情:

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

我正在使用 BASH 执行此操作。

【问题讨论】:

标签: bash for-loop


【解决方案1】:

是的,你可以很容易地做到这一点,但它需要同时从两个不同的文件描述符中读取。您可以简单地将其中一个文件重定向到下一个可用的文件描述符并使用它来提供您的读取循环,例如

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

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

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

输入文件示例

$ 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

【讨论】:

    【解决方案2】:

    在 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
    

    【讨论】:

    • 如果文件很大,这在内存方面可能会非常昂贵。
    【解决方案3】:

    熟悉 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 删除行号。

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

    【讨论】:

      猜你喜欢
      • 2021-10-26
      • 2013-10-07
      • 2013-10-04
      • 2013-03-28
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多