![使用 sed 或 awk 从已知字符串开头和结尾的特定列中删除字符串](https://linux22.com/image/132437/%E4%BD%BF%E7%94%A8%20sed%20%E6%88%96%20awk%20%E4%BB%8E%E5%B7%B2%E7%9F%A5%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%BC%80%E5%A4%B4%E5%92%8C%E7%BB%93%E5%B0%BE%E7%9A%84%E7%89%B9%E5%AE%9A%E5%88%97%E4%B8%AD%E5%88%A0%E9%99%A4%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
我的文件包含这样的行:
1 10241 rs960927773 POS=10241;VP=0x05;GINFO=DDX11L1:100287102;R5;ASP
我想删除第 4 列中以 POS 开头并以 ;GINFO= 结尾的所有内容
我认为这可能有效:sed -e 's/POS=.*;GINFO=//‘ file > new_file
如果可以的话具体如何指向第4栏呢?
答案1
要直接寻址第四列,请使用以下命令awk
方法:
awk '{ sub(/^POS.*GINFO=/, "", $4) }1' file > new_file
$4
- 指向第四个字段sub(/^POS.*GINFO=/, "", $4)
/^POS.*GINFO=
- 替换第 4 个字段中模式给出的子字符串
答案2
如果您所指的列和已知的列用空格分隔,那么您可以执行以下操作:
sed -E 's/^(([^ ]* ){3})POS=.*;GINFO=/\1/' infile
此^(([^ ]* ){3})
匹配从请求该行开始,^
直到*
看到[^ ]
第一个空格为止,并重复此操作最多{3}
次数;括号使此匹配成为具有反向引用的分组匹配,\1
稍后我们将其恢复到替换部分s/pattern/replace/
。
这(...)POS=.*;GINFO=
也匹配POS=
后面的任何内容,.*
直到;GINFO
看到并将从输出中删除。
对于下面给出的示例数据:
1 10241 POS=rs960927773 POS=10241;VP=0x05;GINFO=DDX11L1:100287102;R5;ASP
1 POS=10241 rs960927773 POS=10241;VP=0x05;GINFO=DDX11L1:100287102;R5;ASP
POS=1 10241 rs960927773 POS=10241;VP=0x05;GINFO=DDX11L1:100287102;R5;ASP
会返回一个结果:
1 10241 POS=rs960927773 DDX11L1:100287102;R5;ASP
1 POS=10241 rs960927773 DDX11L1:100287102;R5;ASP
POS=1 10241 rs960927773 DDX11L1:100287102;R5;ASP
POSIXly 版本可能是:
sed 's/^\([^ ]* \)\([^ ]* \)\([^ ]* \)POS=.*;GINFO=/\1\2\3/' infile
答案3
在 POSIXly sed 中我们可以这样做:
sed -ne '
#place a markholder at the beginning of the 4th field
s/[^[:blank:]][[:blank:]]\{1,\}/&\
/3
# perform the sub on the 4th field
s/\nPOS=.*;GINFO=//p
' input_file