如何用sed替换一系列字符串中的一系列数字

How to replace a range of numbers from a range of strings with sed

我正在尝试修改给定的文本文件,其中我想 change/alter 以下字符串,例如:

lcl|NC_018257.1_cds_XP_003862892.1_5067
lcl|NC_018241.1_cds_XP_003859498.1_1683
lcl|NC_018256.1_cds_XP_003862456.1_4633
lcl|NC_018237.1_cds_XP_003858978.1_1163
lcl|NC_018254.1_cds_XP_003861926.1_4104

这样它只包含字符串的 XP_n.1 部分。

我已经成功删除了字符串中的 lcl|NC\_*.1_cds\_ 部分 我使用了以下 sed 命令:

sed 's/lcl|NC\_.\*_cds_//g' cds.fa > cds4.fa

生成的文本文件包含类似 XP_003862892.1_5067.

的字符串

XP_*.1_1XP_*.1_8014大约有8014个这样的字符串。我想把字符串的_1_8014部分删掉,换成1.

我试过使用

sed 's/1\_./1/g'

它似乎奏效了,但是当我进一步向下滚动字符串列表时,两位数字没有被替换——只有一个数字被替换,它紧跟在 '_' 之后,结果第一个数字变为 1,其余保留其原始身份。与三位数和四位数相同。 例如:

XP_003857837.1_23   --->   XP_003857837.13
XP_003857942.1_228  --->   XP_003857942.128

我完全不知道如何删除它,我所有的尝试都以失败告终。有些人问我我想要的输出应该是什么样子,理想的输出应该是:XP_003857837.1,每个字符串后面应该跟一个 .1 而不是 .1_SomeNumberRangingFrom1to8014

您可以使用稍微复杂一点的正则表达式一次性完成所有操作。

sed 's/lcl|NC_.*_cds_\(XP_[0-9.]*\)_.*//' cds.fa > cds4.fa

反斜杠括号创建一个捕获组,替换中的 </code> 调用第一个捕获组(<code> 调用第二个,以此类推,如果您有多个捕获组)。组内的正则表达式查找 XP_ 后跟数字和点,之后的表达式匹配下一个 uderscore 上的其余行。

换句话说,这基本上是说“用我们关心的部分替换整行”。

顺便说一句,没有理由在任何地方使用反斜杠下划线,s 命令的 /g 选项只有在您想要替换多次 时才有意义相同的输入行。

使用sed

$ sed 's/.*_\?\(XP_[^.]*\.\)[^_]*_[0-9]\(.*\)//'
XP_003862892.1067
XP_003859498.1683
XP_003862456.1633
XP_003858978.1163
XP_003861926.1104
XP_003857837.13
XP_003857942.128