0

有没有办法在 bash 脚本中同时读取两个文件?类似于在编程语言示例中使用 & 的东西:

for i in $(cat filea.txt) & for j in $(cat fileb.txt)
do
    if "$j" = "$i"
    then echo "$i"
    fi
done

含义:我希望将 filea 的第 1 行与 fileb 的第 1 行进行比较,并将 filea 的第 2 行与 fileb 的第 2 行进行比较,依此类推。

4

2 回答 2

2

你可以做的是比较线条而不是单词,有点扭曲,但是:

while read -r -u 3 line1 && read -r -u 4 line2
do
    if [ "$line1" = "$line2" ]
    then echo "$line2"
    fi
done 3<filea.txt 4<fileb.txt

我已经明确使用文件描述符 3 和 4 来实现对称性(Polya:“尽量对称地对待对称性,不要肆意破坏任何自然对称性”);也可以这样写,但不太清楚:

while read -r line1 && read -r -u 3 line2
do
    if [ "$line1" = "$line2" ]
    then echo "$line2"
    fi
done <filea.txt 3<fileb.txt

read -u 代表什么,3 和 4 代表什么?

阅读精美手册——该bash手册可在线获得,如果您还没有将其添加为书签,那么现在是添加书签的好时机。

-ufd选项表示“从指定的文件描述符(示例代码中的 3 或 4)而不是从标准输入(当然是文件描述符 0)读取。3 和 4 代表要读取的文件描述符。该代码在循环期间重定向文件描述符 3filea.txt和文件描述符 4 。任何读取文件描述符 3 的进程都将从; 同上 4. 该脚本指示一个命令从 3 读取,另一个命令从 4 读取,并读取行,因此最终效果是,当两个和都有可用数据时,循环将运行,比较两行并打印。fileb.txtwhilefilea.txtreadreadfilea.txtfileb.txt

如果您的目标是打印两个文件之间共有的行,那么使用该comm命令要好得多 - 请参阅Jonas Elfström答案以了解如何做到这一点。

假设您的目标是从两个文件中并行读取,我无法立即想到另一种方法来执行此操作bash。如果您需要并行来自两个文件的单词(这是for i in $(<filea.txt)符号所给出的),您可能需要将进程替换与 I/O 重定向结合使用:

while read -r -u 3 word1 && read -r -u 4 word2
do
    if [ "$word1" = "$word2" ]
    then echo "$word2"
    fi
done 3< <(printf "%s\n" $(<filea.txt)) 4< <(printf "%s\n" $(<fileb.txt))

还有其他方法可以实现这一点,特别是使用tr而不是printf,如果文件很大(很多兆字节)会更好。

于 2013-08-07T06:49:31.960 回答
1

如果目标是输出两个文件中相同的行,那么您可以使用comm

comm -12 file1 file2

但是如果你真的需要遍历两个文件,那么你可以使用文件描述符。

#! /bin/bash
while read -r lineF1 <&3 && read -r lineF2 <&4; do
  echo "$lineF1"
  echo "$lineF2"
done 3<file1 4<file2
于 2013-08-07T06:49:39.960 回答