我有一个巨大的文件要解析并需要搜索和替换文本,但在特定字段中,共享一个名为 dest 的小样本以供参考。第一行是标题供参考。
cat dest
ID|NAME|COMPANY|NUMBER
1001|Adam||15001
1002|eve|adam&eve|15002
1003|||
1004|||50000
1005|||50001
我有单独的文件,其中包含要匹配的模式、要替换的文本和要替换的文本
cat src
1003||15003
1004|50000|15004
1005|50001|15005
所以我可以使用 sed 运行下面给定的 while 循环来实现 src 文件中的最后 2 行。
cat src | while IFS=$'|'; read id old new; do sed -i "/^${id}/s/${old}/${new}/" dest; done
但是对于ID=1003
我得到空字符串$old
,它将替换该ID的dest文件中的所有空列。我想避免。我想要做的是只替换最后一个字段。
期望:
ID|NAME|COMPANY|NUMBER
1001|Adam||15001
1002|eve|adam&eve|15002
1003|||15003
1004|||15004
1005|||15005
当涉及到柱状数据时,我可以使用 awk,因为它更细化。但据我了解,awk 会多次打印到标准输出,这在我的情况下也不实用。
那么有没有一种方法可以让我以简洁明了的方式做到这一点?
FS :字段分隔符
OFS :输出字段分隔符_
NR==FNR:第一个输入文件的始终为真条件习语。
NR表示awk读取的记录总数;FNR是
每个单独文件的记录数。
id[$1, $2]=$3
: 关联的 awk 数组。名称:id
键:column#1+column#2
值:column#3
第一个块仅针对第一个输入文件运行,即。e,文件src。
在此,我们正在更新第二个文件 i
$4=($1, $4) in id? id[$1, $4]: $4
的最后一列($NF
或)的值。$4
e,从id数组中column#1+column#4的匹配键组合文件dest,如果找到则返回该值(),否则复制其当前值。id[$1, $4]
另一种
awk
解决方案,它假设来自的行src
将按顺序使用一次。这允许我们只跟踪下一行,src
直到它被使用,然后读取下一行。如果标志
have
未设置或为零,则下一行 fromsrc
被读入line
并拆分到数组pat
中。这是在! have
块中完成的。如果当前输入行的
dest
第一个字段与 的第一个元素相同pat
,那么我们将针对第 4 个字段进行测试,如果它们相同,则将其pat[2]
替换为。pat[3]
然后将该have
标志重置为零以触发从 中读取新行src
。1
程序末尾的尾随awk
导致(可能已修改)记录被输出。给定问题中的数据,输出: