![使用 awk 比较 shell 脚本中两个制表符分隔的文件](https://linux22.com/image/891394/%E4%BD%BF%E7%94%A8%20awk%20%E6%AF%94%E8%BE%83%20shell%20%E8%84%9A%E6%9C%AC%E4%B8%AD%E4%B8%A4%E4%B8%AA%E5%88%B6%E8%A1%A8%E7%AC%A6%E5%88%86%E9%9A%94%E7%9A%84%E6%96%87%E4%BB%B6.png)
我已经编写了这段代码,但是我面临如下提到的问题。
我的代码是:
paste 1.txt 2.txt|
awk ' { FS = "\t " } ; NR == 1 { n = NF/2 }
{for(i=1;i<=n;i++)
if($i!=$(i+n))
{c = c s i; s = "," }
if(c)
{print "Line No. " NR-1 " COLUMN NO " c;
c = "" ; s = "" } } '
预期输出:
Line No. 2 COLUMN NO 2,3
Line No. 4 COLUMN NO 1,2,3,4
Line No. 6 COLUMN NO 2,3,4,5
Line No. 7 COLUMN NO 1,2,3,4,5
正在生成的输出:
Line No. 2 COLUMN NO 2,3
Line No. 4 COLUMN NO 1,2,3,4
Line No. 6 COLUMN NO 2,3,4,5
Line No. 7 COLUMN NO 1,2,3,4
下面指定的文件以空格分隔。为了更好地理解它,我将其格式化如下。
文件1:
ID_ID First_name Last_name Address Contact_Number
ID1 John Rock 32, Park Lake, California 2222200000
ID2 Tommy Hill 5322 Otter Lane Middleberge 3333300000
ID3 Leonardo Test Half-Way Pond, Georgetown 4444400000
ID8 Rhyan Bigsh 6762,33 Ave N,St. Petersburg 5555500000
ID50 Steve Goldberg 6762,33 Ave N,St. Petersburg 6666600000
ID60 Steve Goldberg 6666600000
文件2:
ID_ID First_name Last_name Address Contact_Number
ID1 John Rock 32, Park Lake, California 2222200000
ID2 Tommy1 Hill1 5322 Otter Lane Middleberge 3333300000
ID3 Leonardo Test Half-Way Pond, Georgetown 4444400000
ID80 Sylvester Stallone 5555500000
ID50 Steve Goldberg 6762,33 Ave N,St. Petersburg 6666600000
ID60 Mark Waugh St. Petersburg 7777700000
ID70 John Smith 8888800000
答案1
这里有个提示。输出:
paste 1.txt 2.txt | awk '
{ FS = "\t" }
NR == 1 { n = NF/2 } {
for(i=1;i<=n;i++) print "\"" $i "\" " ($i == $(i+n) ? "==":"!=") " \"" $(i+n) "\""
print "###############"
}'
比较并打印文件之间每条记录的每个字段,结尾如下:
"ID60" == "ID60"
"Steve" != "Mark"
"Goldberg" != "Waugh"
"" != "St. Petersburg"
"6666600000" != "7777700000"
###############
"" != "8888800000"
"ID70" != ""
"John" != ""
"Smith" != ""
"" == ""
###############
有两个错误:
如果一行只存在于第二个文件中,则会出现隐藏的差一错误。这是因为缺少一条记录一字段,在通过 添加的制表符之前有一个空字符串
paste
。因此,在这种情况下,您实际上是按 5,1,2,3,4 的顺序比较字段。两个文件中此行的字段 4 都是空的(尽管方式不同),因此我期望输出:
Line No. 7 COLUMN NO 1,2,3,5
为了获得您想要的准确输出,下面的粗略修复将报告如果一行仅存在于一个文件中,则所有字段均不匹配。这可以通过NF == n+1
添加到 来检测if
,因为对于仅存在于一个文件中的行,应该只有n+1
和2*n
字段,无论该文件是哪个文件。
paste 1.txt 2.txt | awk '
{ FS = "\t" }
NR == 1 { n = NF/2 } {
for(i=1;i<=n;i++) if(NF == n+1 || $i!=$(i+n)) {c = c s i; s = "," }
if(c){print "Line No. " NR-1 " COLUMN NO " c; c = "" ; s = "" }
}'
这假设所有记录都包含正确数量的标签n-1
。