如何使用 Diff 命令忽略一行中的文本并根据条件获取不匹配的数据

如何使用 Diff 命令忽略一行中的文本并根据条件获取不匹配的数据

我正在尝试使用给定的输入获得以下输出。这可以通过diff命令完成吗?我正在尝试这种语法但不起作用:

diff -a  --suppress-common-lines a.txt b.txt

这是两个输入文件:

第一的a.txt

abc abc/d_4.1/efg 35 
xyz abc/d_4.1/efg 36
mno abc/d_4.1/efg 38

b.txt

abc abc/d_4/efg 35
xyz abc/d_4/efg 36
mno abc/d_4/efg 40

我需要这个输出(下面是两个文件中的diff输出):d_4.1d_4

mno abc/d_4.1/efg 38
mno abc/d_4/efg  40

答案1

实用程序diff没有跳过字段的选项。

我试图让它与 cut & uniq 一起工作。认为下面的方法可行,但输出中将缺少第 2 列。

$ cut -d/ -f1,3 file1 file2 |sort |uniq -u  #column 2 is skipped

作为更正确的解决方案,我提出以下 awk:

awk -F" |/" '{a=$1$2$4$5;seen[a]++;out[a]=$0}END{for (i in seen) if (seen[i]==1) print out[i]}' file1 file2

我使用字段分隔符空格或斜杠 / ,因为给定的输入数据在每行末尾包含一些额外的空格。

即使您的真实数据不包含额外的空格,上述解决方案仍然可以正常工作。

awk 的逻辑如下:它模拟 uniq -u ,跳过中间列 ( /d_4/)。
它只是打印 file1 和 file2 之间的所有唯一行(由 awk 连接)。

测试(另请参阅在线测试

cat file1 
cat file2 
echo "awk start:"
awk -F" |/" '{a=$1$2$4$5;seen[a]++;out[a]=$0}END{for (i in seen) if (seen[i]==1) print out[i]}' file1 file2
echo "awk end"

#Output
#file1            
abc abc/d_4.1/efg 35
xyz abc/d_4.1/efg 36 
mno abc/d_4.1/efg 38
#file2
abc abc/d_4/efg 35
xyz abc/d_4/efg 36 
mno abc/d_4/efg 40

awk start:      
mno abc/d_4/efg 40
mno abc/d_4.1/efg 38
awk end

答案2

使用awk, 并在 上拆分/,当第一个字段匹配而第三个字段不匹配时,此代码将打印两行。

代码:

#!/bin/awk -f
BEGIN { FS = OFS = "/" }

$1 in a2 && $3 != a2[$1] {
    print $1, a1[$1], a2[$1]
    print
}
{
    a1[$1] = $2
    a2[$1] = $3
}

结果:

$ awk -f test.awk file1 file2
mno abc/d_4.1/efg 38
mno abc/d_4/efg 40

相关内容