awk文件比较

时间:2015-10-19 12:08:42

标签: awk nawk

两个文件,其组件名称和版本号用空格分隔:

cat file1
com.acc.invm:FNS_PROD 94.0.5
com.acc.invm:FNS_TEST_DCCC_Mangment 94.1.6
com.acc.invm:FNS_APIPlat_BDMap 100.0.9
com.acc.invm:SendEmail 29.6.113
com.acc.invm:SendSms 12.23.65
com.acc.invm:newSer 10.10.10

cat file2 
com.acc.invm:FNS_PROD 94.0.5
com.acc.invm:FNS_TEST_DCCC_Mangment 94.0.6
com.acc.invm:FNS_APIPlat_BDMap 100.0.10
com.acc.invm:SendEmail 29.60.113
com.acc.invm:SendSms 133.28.65
com.acc.invm:distri_cob 110.10.10

需要的输出是:

(1)file1中的组件列表,它们位于file1中,不存在于file2中  (2)来自file2的组件列表,这些组件在file1中,而不在file2中。

在此示例中,所需的输出为:

来自file1的

组件:

com.acc.invm:newSer 10.10.10
来自file2的

组件:

com.acc.invm:distri_cob 110.10.10

注意:我们必须忽略组件是否存在不同版本。

我的代码是: (1)

 cat new.awk
 { split($2,a,/\./); curr = a[1]*10000 + a[2]*100 + a[3] }
 NR==FNR { prev[$1] = curr; next }
 !($1 in prev) && (curr > prev[$1])

 /usr/bin/nawk -f new.awk f2 f1

输出

com.acc.invm:newSer 10.10.10

(2)

/usr/bin/nawk -f new.awk f1 f2

输出

com.acc.invm:distri_cob 110.10.10

这个逻辑是否正确?和

任何人都可以帮助我如何在我的脚本中编写new.awk,因此不需要new.awk文件来运行它。

3 个答案:

答案 0 :(得分:1)

我可以建议一个简单的单线程做同样但没有awk编程吗?

cat file2 file1 file2|cut -f 1 -d" "|sort|uniq -u| xargs -I'{}' grep '{}' file1
com.acc.invm:newSer 10.10.10


cat file1 file2 file1|cut -f 1 -d" "|sort|uniq -u| xargs -I'{}' grep '{}' file2
com.acc.invm:distri_cob 110.10.10

答案 1 :(得分:1)

您可以通过一次调用awk来打印两个文件中的唯一组件:

# Save all the components from the first file into an array
NR == FNR { a[$1] = $0; next }

# If a component from the second file is found, delete it from the array
$1 in a { delete a[$1]; next }

# If a component in the second file is not found, print it
{ print }

# Print all the components from the first file that weren't in the second
END { for (i in a) print a[i] }


$ cat file1
com.acc.invm:FNS_PROD 94.0.5
com.acc.invm:FNS_TEST_DCCC_Mangment 94.1.6
com.acc.invm:FNS_APIPlat_BDMap 100.0.9
com.acc.invm:SendEmail 29.6.113
com.acc.invm:SendSms 12.23.65
com.acc.invm:newSer 10.10.10


$ cat file2
com.acc.invm:FNS_PROD 94.0.5
com.acc.invm:FNS_TEST_DCCC_Mangment 94.0.6
com.acc.invm:FNS_APIPlat_BDMap 100.0.10
com.acc.invm:SendEmail 29.60.113
com.acc.invm:SendSms 133.28.65
com.acc.invm:distri_cob 110.10.10


$ awk -f cf.awk file2 file1
com.acc.invm:newSer 10.10.10
com.acc.invm:distri_cob 110.10.10

对于问题的第二部分,如果你想在没有单独的awk文件中的代码的情况下运行它,你可以像这样内联代码:

 awk 'NR==FNR {a[$1]=$0; next} $1 in a {delete a[$1]; next}1 END {for (i in a) print a[i]}' file2 file1

(请注意1之前的END{ print }相同,因为1始终为true,print是默认操作。 )

答案 2 :(得分:1)

如果您只需要组件名称(没有版本)

$ p() { cut -d' ' -f1 $1 | sort; }; comm -23 <(p file1) <(p file2)
com.acc.invm:newSer

$ p() { cut -d' ' -f1 $1 | sort; }; comm -13 <(p file1) <(p file2)
com.acc.invm:distri_cob

如果您需要版本号,可以输入

 ... | xargs -I{} grep {} file2

类似于file1,就像@LiMar的解决方案

一样