完成规范:
- 行号是否实际存在于文件中?是的
- 什么列组合告诉您 File1 中的条目与 File2 中的条目匹配?行号
- 标题行是否实际存在于文件中?不(但我们稍后会改变主意)
- 文件中的数据是否已排序?假设没有
- File1 中存在但 File2 中不存在的记录如何处理?未指定,但可能需要第三个输出文件。
答案将忽略“已删除记录”问题。
问题观察到这个逻辑找到插入在 File2 中的记录:
awk 'NR==FNR{a[$1]++;next;}!($0 in a)' file2 file1
它接近正确;它应该是!($1 in a)
。需要显式打印才能将输出发送到文件。对于其余的逻辑,我们可以很容易地发现字段的变化:
awk 'NR == FNR { a[$1] = $0; next }
!($1 in a) { print $0 > "ofile.1"; next }
{ split(a[$1], old);
for (i = 2; i <= NF; i++)
{
if ($i != old[i])
{
format = "%-8s %4d %d %s\n"
printf format, "File1", $1, i, $i > "ofile.2";
printf format, "File2", $1, i, old[i] > "ofile.2";
}
}
}'
这会在给定的假设下产生合理的输出(没有标题行)。如果实际上存在标题行,那么您必须捕获并使用它们(以及文件名):
awk 'FNR == 1 { file[++num] = FILENAME; for (i = 1; i <= NF; i++) head[i] = $i; next }
NR == FNR { a[$1] = $0; next }
!($1 in a) { print $0 > "ofile.1"; next }
{ split(a[$1], old);
for (i = 2; i <= NF; i++)
{
if ($i != old[i])
{
format = "%-8s %4d %-4s %s\n"
printf format, file[1], $1, head[i], $i > "ofile.2";
printf format, file[2], $1, head[i], old[i] > "ofile.2";
}
}
}'
为了在第二个输出文件上获得正确的标题,您需要进行一些更小的调整:
awk 'NR == 1 { printf "%-8s %4s %-7s %s\n", "Filename", "Row", "Colname", "Colvalue" > "ofile.2" }
FNR == 1 { file[++num] = FILENAME; for (i = 1; i <= NF; i++) head[i] = $i; next }
NR == FNR { a[$1] = $0; next }
!($1 in a) { print $0 > "ofile.1"; next }
{ split(a[$1], old);
for (i = 2; i <= NF; i++)
{
if ($i != old[i])
{
format = "%-8s %4d %-7s %s\n"
printf format, file[1], $1, head[i], $i > "ofile.2";
printf format, file[2], $1, head[i], old[i] > "ofile.2";
}
}
}' File1 File2
此示例输出为:
文件.1
3 M N O P
外地.2
Filename Row Colname Colvalue
File1 1 Col2 Z
File2 1 Col2 B
File1 2 Col3 Y
File2 2 Col3 G
如果你想在每条记录后有空行,那是一个微不足道的修改——OP 练习。