我正在处理名为test的长文件,如下所示:
AHAP USA|NIS00333|+NULL|NISGOOGLE|NIS00005|*binary|NISCAR
KJJLIL123124%|NIS00160|+NULL|NISFACEBOOK|NIS00006|*binary|NISBUR
ASFASS9992|NIS00164|+NULL|NISTABLE|NIS00008|*binary|NISFANCY
我需要将字符串“NIS”替换为“NIX”,但是我只需要在由管道字符分隔的第二列中实现这一点,我的数据的分隔符是管道“|”,我有几列,总共七列,我只想在第二列中进行替换。
我试过了:
$ sed s/NIS/NIX/g test
AHAP USA|NIX00333|+NULL|NIXGOOGLE|NIX00005|*binary|NIXCAR
KJJLIL123124%|NIX00160|+NULL|NIXFACEBOOK|NIX00006|*binary|NIXBUR
ASFASS9992|NIX00164|+NULL|NIXTABLE|NIX00008|*binary|NIXFANCY
但它影响了与字符串匹配的所有列:NIS并将其更改为NIX,我只想影响第二列,我想要的输出将是:
AHAP USA|NIX00333|+NULL|NISGOOGLE|NIS00005|*binary|NISCAR
KJJLIL123124%|NIX00160|+NULL|NISFACEBOOK|NIS00006|*binary|NISBUR
ASFASS9992|NIX00164|+NULL|NISTABLE|NIS00008|*binary|NISFANCY
我非常感谢你对这个问题的帮助,谢谢你们。
答案 0 :(得分:3)
如果您遇到列问题,请使用awk
对其进行更好的原生控制:
$ awk 'BEGIN {FS=OFS="|"}{gsub("NIS","NIX",$2)}1' file
AHAP USA|NIX00333|+NULL|NISGOOGLE|NIS00005|*binary|NISCAR
KJJLIL123124%|NIX00160|+NULL|NISFACEBOOK|NIS00006|*binary|NISBUR
ASFASS9992|NIX00164|+NULL|NISTABLE|NIS00008|*binary|NISFANCY
这会对基于2 nd |
的字段执行gsub()
替换。完成此替换后,1
会触发awk
的默认操作,包括打印$0
,其中包含完整(已更新)的记录。
答案 1 :(得分:2)
sed解决方案:
$ sed 's/^\([^|]*|[^|]*\)NIS/\1NIX/' infile
AHAP USA|NIX00333|+NULL|NISGOOGLE|NIS00005|*binary|NISCAR
KJJLIL123124%|NIX00160|+NULL|NISFACEBOOK|NIS00006|*binary|NISBUR
ASFASS9992|NIX00164|+NULL|NISTABLE|NIS00008|*binary|NISFANCY
正则表达式,分手:
^ # Start of line anchor
\( # Start of capture gruop
[^|]* # Characters other than pipe - first column
| # Column separator between first and second column
[^|]* # Characters other than pipe - first part of second column
\) # End of capture group
NIS # What we actually want to replace
这有一个限制,因为它只替换第二列中第一次出现的NIS
。示例输入不再具有,但如果确实如此,我们可以使用条件分支来重复替换,只要它改变了模式空间:
sed '
:a
s/^\([^|]*|[^|]*\)NIS/\1NIX/
ta' infile
:a
是要跳转到的标签,ta
是条件分支命令(如果替换做了某事,“跳转到:a
”。)
作为一个单行:
sed ':a;s/^\([^|]*|[^|]*\)NIS/\1NIX/;ta' infile
BSD sed(在Mac OS中找到)会抱怨标签没有被换行符,所以我们可以重写为
sed -e ':a' -e 's/^\([^|]*|[^|]*\)NIS/\1NIX/;ta' infile