逐行比较BASH中的两个文件

时间:2017-11-04 22:05:32

标签: string bash awk grep comparison

我需要创建一个脚本文件来读取两个文件并打印出它们之间的公共线。我知道两个文件的行数相同,每行只包含一个单词。

文件1:

Blue
Red
Orange
Green
Yellow
Blue

文件2:

Blue
Green
Red
Purple
Yellow
Blue

预期产出:

Blue
Yellow
Blue

因此,在示例中,红色和绿色出现在两个文件中,但它们不在每个文件的同一行,因此会被忽略。

尝试过使用awk,grep和comm但是无法让它们工作。

尝试找到需要最短时间处理的解决方案。

4 个答案:

答案 0 :(得分:3)

使用awk:

awk 'NR == FNR { lines[NR] = $0 } NR != FNR && lines[FNR] == $0 { print }' file1 file2

说明:

  • 阅读第一个文件(NR == FNR)时,请构建行号到值的映射
  • 当不读取第一个文件(NR != FNR)时,如果当前行与缓存中对应的行匹配,则打印行

这两次只读取两个文件, 并使用与第一个文件大小相同的内存。

答案 1 :(得分:3)

使用paste和GNU grep。一步一步。

paste -d '|' file1 file2

输出:

Blue|Blue
Red|Green
Orange|Red
Green|Purple
Yellow|Yellow
Blue|Blue
paste -d '|' file1 file2 | grep -Po '^(.*)\|+\1$'

输出:

Blue|Blue
Yellow|Yellow
Blue|Blue

使用\K

paste -d '|' file1 file2 | grep -Po '^(.*)\|+\K\1$'

输出:

Blue
Yellow
Blue

我认为|不在您的文件中。

答案 2 :(得分:2)

pasteawk

paste -d'|' file1 file2 | awk -F'|' '$1==$2 {print $1}'

我喜欢使用来自@Cyrus的paste,但我认为合并行的比较更容易与awk进行比较。在这种情况下,-F负责使用相同的分隔符|,将第一位$1与第二位$2进行比较非常简单。输出可以是一个。

还假设|不是输入文件的一部分。可以选择任何其他角色。

如果输入文件的每一行只包含一个单词,则它会更短并且也可以工作:

paste file1 file2 | awk '$1==$2 {print $1}'

答案 3 :(得分:1)

更多方式,

awk 'FNR==NR{a[FNR,$1];next}(FNR,$1) in a' file1 file2

测试结果:

$ cat f1
Blue
Red
Orange
Green
Yellow
Blue

$ cat f2
Blue
Green
Red
Purple
Yellow
Blue

$ awk 'FNR==NR{a[FNR,$1];next}(FNR,$1) in a' f1 f2
Blue
Yellow
Blue