我有 2 个文件,每个文件包含相同数量的 4 行记录,且顺序相同:
fileA
:
record1 line1=header
record1 line2 X <= this is different but should be ignored
record1 line3 id ABC
record1 line4
record2 line1=header
record2 line2
record2 line3 id DEF <= this is different
record2 line4
fileB
:
record1 line1=header
record1 line2 Y <= this is different but should be ignored
record1 line3 id ABC
record1 line4
record2 line1=header
record2 line2
record2 line3 id GHI <= this is different
record2 line4
对于每条记录,我想比较line3
两个文件之间的情况,如果line3
不同,则保存 fileB 的整个记录(第 1-4 行);在上面的示例中,record1 将被忽略并保存 record2。我有基本知识,diff
但不确定它是否可行。首先,我不知道如何只比较每第三行并忽略其他行;第二,-C
定义对称的上下文,即差异之前和之后的行数相同......
UPD。最初,我在示例中犯了一个错误:记录之间有空行,而我的真实文件中没有该空行。我对此表示歉意。根据@stteldriver的回答,我有以下解决方案:
awk '
NR%4==3 {
lineA3=$0;
getline lineB1 < "fileB";
getline lineB2 < "fileB";
getline lineB3 < "fileB";
getline lineB4 < "fileB";
if (lineA3 != lineB3) {printf "%s\n%s\n%s\n%s\n", lineB1,lineB2,lineB3,lineB4;}
}' fileA
它工作完美!虽然代码相当丑陋(我才刚刚开始学习awk
!),如果您能优化它,我将不胜感激。
答案1
对于更新的输入,严格基于 4 行记录,您可以使用模算术来维护当前记录的数组,并每隔 4 行检查第 3 行是否匹配:
$ awk '
{a[FNR%4] = $0; getline b[FNR%4] < "fileB"}
!(FNR%4) && b[3] != a[3] {
for(i=0;i<4;i++) print b[i%4]
}
' fileA
record2 line1=header
record2 line2
record2 line3 id GHI <= this is different
record2 line4
(请注意,确实应该检查命令的返回值getline
,并在失败时执行一些明智的操作)。
对于您最初发布的输入,您可以使用段落模式:
$ awk -vRS= -F'\n' '{A3 = $3}; getline "fileB" > -1 && $3 != A3' fileA
record2 line1=header
record2 line2
record2 line3 id DEF <= this is different
record2 line4
对于正常处理(来自 的输入)和(来自 的输入),空RS
会导致读取整个空行分隔的记录。将字段分隔符设置为换行符 ( ) 然后允许我们保存其中的整行并与另一行进行比较。如果它们不相等,则默认打印输出(这是of 的整个记录)。fileA
getline
fileB
\n
$3
$0
getline
fileB
答案2
这是一个可以执行您想要的操作的 Python 脚本:
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
"""compare.py"""
import sys
file_A = open(sys.argv[1], "r")
file_B = open(sys.argv[2], "r")
records_A = file_A.read().split("\n\n")
records_B = file_B.read().split("\n\n")
for record_A, record_B in zip(records_A, records_B):
lines_A = record_A.split("\n")
lines_B = record_B.split("\n")
if lines_A[2] != lines_B[2]:
print("{}\n".format(record_B))
你可以像这样运行它:
python compare.py fileA fileB
当我在示例数据上运行它时,我得到了所需的输出:
record2 line1=header
record2 line2
record2 line3 id GHI <= this is different
record2 line4