比较 bash 中两个文件中除最后 N 列以外的所有列
Compare all but last N Columns across two files in bash
我有 2 个文件:一个有 18 列;另一个有更多。我需要仅在前 18 列中找到不匹配的行,而忽略其他文件中的其余部分。但是,我需要保留并打印整行(剪切不起作用)。
文件 1:
F1 F2 F3....F18
A B C.... Y
AA BB CC... YY
文件 2:
F1 F2 F3... F18... F32
AA BB CC... YY... 123
AAA BBB CCC... YYY...321
输出不在文件 1 中:
AAA BBB CCC YYY...321
输出不在文件 2 中:
A B C...Y
如果可能的话,我希望尽可能少地使用 diff 或 awk。
你可以使用 awk:
awk '{k=""; for(i=1; i<=18; i++) k=k SUBSEP $i} FNR==NR{a[k]; next} !(k in a)' file1 file2
- 对于两个文件中的每一行,我们首先通过连接前
18
个字段 创建一个键
- 然后我们在迭代第一个文件时将此键存储在关联数组中
- 最后,当在我们的关联数组中找不到这个新键值时,我们打印第二个文件的每一行。
你可以使用 grep:
grep -vf file1 file2
grep -vf <(cut -d" " -f1-18 file2) file1
要获得两个文件之间的设置差异,您只需要一点点,类似于@anubhava 的回答
$ awk 'NR==FNR{f1[[=10=]]; next}
{k=; for(i=2;i<=18;i++) k=k FS $i;
if(k in f1) delete f1[k];
else f2[[=10=]]}
END{print "not in f1";
for(k in f2) print k;
print "\nnot in f2";
for(k in f1) print k}' file1 file2
可以重写以保留 file2
中的顺序
$ awk 'NR==FNR{f1[[=11=]]; next}
{k=; for(i=2;i<=18;i++) k=k FS $i;
if(k in f1) delete f1[k];
else {if(!p) print "not in f1";
f2[[=11=]]; print; p=1}}
END{print "\nnot in f2";
for(k in f1) print k}' file1 file2
我有 2 个文件:一个有 18 列;另一个有更多。我需要仅在前 18 列中找到不匹配的行,而忽略其他文件中的其余部分。但是,我需要保留并打印整行(剪切不起作用)。
文件 1:
F1 F2 F3....F18
A B C.... Y
AA BB CC... YY
文件 2:
F1 F2 F3... F18... F32
AA BB CC... YY... 123
AAA BBB CCC... YYY...321
输出不在文件 1 中:
AAA BBB CCC YYY...321
输出不在文件 2 中:
A B C...Y
如果可能的话,我希望尽可能少地使用 diff 或 awk。
你可以使用 awk:
awk '{k=""; for(i=1; i<=18; i++) k=k SUBSEP $i} FNR==NR{a[k]; next} !(k in a)' file1 file2
- 对于两个文件中的每一行,我们首先通过连接前
18
个字段 创建一个键
- 然后我们在迭代第一个文件时将此键存储在关联数组中
- 最后,当在我们的关联数组中找不到这个新键值时,我们打印第二个文件的每一行。
你可以使用 grep:
grep -vf file1 file2
grep -vf <(cut -d" " -f1-18 file2) file1
要获得两个文件之间的设置差异,您只需要一点点,类似于@anubhava 的回答
$ awk 'NR==FNR{f1[[=10=]]; next}
{k=; for(i=2;i<=18;i++) k=k FS $i;
if(k in f1) delete f1[k];
else f2[[=10=]]}
END{print "not in f1";
for(k in f2) print k;
print "\nnot in f2";
for(k in f1) print k}' file1 file2
可以重写以保留 file2
中的顺序$ awk 'NR==FNR{f1[[=11=]]; next}
{k=; for(i=2;i<=18;i++) k=k FS $i;
if(k in f1) delete f1[k];
else {if(!p) print "not in f1";
f2[[=11=]]; print; p=1}}
END{print "\nnot in f2";
for(k in f1) print k}' file1 file2