我有一个这样的文件:
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211
3;1471383211;frank;WO12345;1471385211
4;1471385311;frank;WO12345;
5;1471385311;joe;WO12346;1471388211
我想使用 bash 脚本来查找包含指定名称(如frank
)以及指定的 WO 编号(如WO12345
)且以 结尾的行;
,然后在该行末尾添加一个字符串。我想直接编辑文件,而不是输出到标准输出。我知道如何read
获取姓名和 WO 号码。我猜sed
with-i
是正确的工具。我怎样才能做到这一点?
答案1
如果 name 和 WO 总是连续的,那就很简单了:
sed '/frank;WO12345;/s/;$/;sometext/' -i file
如果它们可以以任意方式出现,或者不一定彼此相邻,请使用命令块来组合这两个测试:
sed '/;frank;/{/;WO12345;/s/;$/;sometext/}' -i file
答案2
awk
更适合字段分隔的数据。
使用awk
:
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
替换;Foobar
为您想要在末尾插入的内容。
在这里,我们检查;
分隔的第三个和第四个字段是否与所需的字符串匹配,如果是,则;Foobar
在末尾添加字符串。
最新的 GNU awk
(>=4.10) 有就地编辑选项:
awk -i inplace -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
如果您没有sponge
从 GNUmoreutils
或临时文件中使用该功能:
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt | sponge file.txt
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' \
file.txt >file_temp.txt && mv file_temp.txt file.txt
如果你坚持sed
:
sed -Ei '/^([^;]*;){2}frank;WO12345;/ s/$/;Foobar/' file.txt
([^;]*;){2}
匹配前两个字段,然后我们检查是否需要第三个和第四个字段,然后完成替换
例子:
$ cat file.txt
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211
3;1471383211;frank;WO12345;1471385211
4;1471385311;frank;WO12345;
5;1471385311;joe;WO12346;1471388211
$ awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
2;1471378551;frank;WO12345;1471380211;Foobar
3;1471383211;frank;WO12345;1471385211;Foobar
4;1471385311;frank;WO12345;;Foobar
$ sed -E '/^([^;]*;){2}frank;WO12345;/ s/$/;Foobar/' file.txt
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211;Foobar
3;1471383211;frank;WO12345;1471385211;Foobar
4;1471385311;frank;WO12345;;Foobar
5;1471385311;joe;WO12346;1471388211