使用具有不同分隔符的 sed 查找特定条件为真时的 Bash

Posted

技术标签:

【中文标题】使用具有不同分隔符的 sed 查找特定条件为真时的 Bash【英文标题】:Bash finding when specific condition is true using sed with different delimiter 【发布时间】:2022-01-01 06:25:43 【问题描述】:

类似于Bash replace string where specific condition is true 询问我想根据先验条件替换行的一部分,但我的分隔符必须不同,因为我要替换的部分内容包括 /。条件也不在第一列,而是在第二列。

例如我的数据包括:

Location Ref Alt GT1 GT2
1_100004338 T C 0/0 0/0
1_100004339 C T 0/0 0/1
1_100004343 A G 1/1 0/0

如果我想基于 Ref 中是否有 C(第 2 列)并将所有出现的 0/0 替换为 2:

Location Ref Alt GT1 GT2
1_100004338 T C 0/0 0/0
1_100004339 C T 2 0/1
1_100004343 A G 1/1 0/0

我尝试了以下输入

sed "+^"C"+s+"0/0"+"2"+g" file

并得到错误

sed: -e expression #1, char 2: unknown command: `^'

我不确定如果它起作用的话它是否会给我我想要的东西,尽管 C 位于第二列而不是行首。我尝试过使用 awk BEGIN 等其他方式,这会降低我的文件大小。

任何帮助将不胜感激,并提前致谢。

【问题讨论】:

您只能使用s 命令修改分隔符。当使用正则表达式匹配行时,必须使用/ 分隔符。 【参考方案1】:

这可能对你有用(GNU sed):

sed '/^\S\+ C /s#0/0#2#g' file

如果第二列是C,则将所有出现的0/0 替换为2


或者如果您愿意:

sed -E '/^\S+\s+C\s+/s#0/0#2#g' file

【讨论】:

不错。我会用\s+ 替换正则表达式中的空格,以防万一。 @RenaudPacalet 谢谢查看编辑【参考方案2】:

awk 会更适合这个。

$ awk '$2=="C" $4=21' input_file
Location Ref Alt GT1 GT2
1_100004338 T C 0/0 0/0
1_100004339 C T 2 0/1
1_100004343 A G 1/1 0/0

如果$2第2列字符串是C,那么$4第4列等于2。

如果sed是必须的,你可以试试这个。

$ sed '/[^ ]* C [A-Z]/ s|0/0|2|' input_file
Location Ref Alt GT1 GT2
1_100004338 T C 0/0 0/0
1_100004339 C T 2 0/1
1_100004343 A G 1/1 0/0

【讨论】:

以上是关于使用具有不同分隔符的 sed 查找特定条件为真时的 Bash的主要内容,如果未能解决你的问题,请参考以下文章

使用动态名称记录条件为真时的变量值

有条件的重复键更新(仅在特定条件为真时更新)

当某个条件为真时,如何在 Eclipse 中以编程方式设置 C++ 断点?

仅在条件为真时添加指令 [重复]

3列条件为真时获取索引号

Python之三目运算符