如何在字符串和数字模式周围添加双引号?

如何在字符串和数字模式周围添加双引号?

你好,我需要在 30 万行的模式中添加双引号。我尝试使用 sed,并阅读了这里和其他来源的多个询问,但我似乎无法理解它的语法。

我有:

chr1    StringTie       exon    191964  192299  1000    -       .       gene_id MSTRG.201; transcript_id MSTRG.201.53; exon_number 2;
chrY    StringTie       exon    26420508        26420531        1000    +       .       gene_id MSTRG.49889; transcript_id MSTRG.49889.11; exon_number 1;

我需要:

chr1    StringTie       exon    191964  192299  1000    -       .       gene_id "MSTRG.201"; transcript_id "MSTRG.201.53"; exon_number 2;
chrY    StringTie       exon    26420508        26420531        1000    +       .       gene_id "MSTRG.49889"; transcript_id "MSTRG.49889.11"; exon_number 1;

我使用 sed 如下:

sed 's/MSTRG./"MSTRG."/g' filename

但我只能得到:

chr1    StringTie       exon    191964  192299  1000    -       .       gene_id "MSTRG."201; transcript_id "MSTRG."201.53; exon_number 2;
chrY    StringTie       exon    26420508        26420531        1000    +       .       gene_id "MSTRG."49889; transcript_id "MSTRG."49889.11; exon_number 1;

我试过了:

sed -Ei 's|MSTRG[[:digit:]]+|"&"|g' filename
sed 's/M/"M/; s/$/"/' filename
sed 's/MSTRG.[[:digit:]]+/"MSTRG.[[:digit:]]+"/g' filename

但这些都不起作用。

我想知道我是否可以使用 awk,但我不懂这种语言的任何技能。

请问有什么帮助吗?

提前致谢。

答案1

为什么要将自己限制在这个特定的基因名称上?这里有一个更通用的解决方案,它将任何内容放在gene_id引号transcript_id;

$ sed -E 's/(transcript_id|gene_id)  *([^;]+)/\1 "\2"/g' file
chr1    StringTie       exon    191964  192299  1000    -       .       gene_id "MSTRG.201"; transcript_id "MSTRG.201.53"; exon_number 2;
chrY    StringTie       exon    26420508        26420531        1000    +       .       gene_id "MSTRG.49889"; transcript_id "MSTRG.49889.11"; exon_number 1;

解释

  • -E:这启用了扩展正则表达式,让我们可以使用( )未转义的(非\( \))来捕获组,并且还+为我们提供了“一个或多个”并允许我们使用非转义的|“这个或那个”。
  • s/(transcript_id|gene_id) *([^;]+)/\1"\2"/g':我们正在寻找“transcript_id或” gene_id(这就是为什么|使用 ,表示“或”),后跟一个或多个空格(+),然后是一个或多个非;字符。括号用于捕获匹配的内容,因此可以将其用在替换运算符的右侧。第一个捕获的组(此处为transcript_idgene_id以及空格)将是\1,第二个将是\2等等。然后,这些内容将全部替换为首先捕获的内容(\1),然后替换为第二个捕获的内容,并用引号("\2")括起来。
  • s///gg需要进行替换Global,替换在同一行找到的所有匹配项。如果没有g,则只会替换第一个匹配项。

您可以将其用于任意基因名称,甚至整个 GTF 文件,它都应该正常工作。

答案2

使用 GNU sed:

sed -E 's/MSTRG[0-9.]+/"&"/g' file

输出:

chr1 StringTie 外显子 191964 192299 1000 - . gene_id "MSTRG.201"; transcript_id "MSTRG.201.53"; exon_number 2;
chrY StringTie 外显子 26420508 26420531 1000 + . gene_id "MSTRG.49889"; transcript_id "MSTRG.49889.11"; 外显子编号 1;

&:指模式空间中匹配的部分

请参阅:man sedStack Overflow 正则表达式常见问题解答

相关内容