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

Tha*_*les 5 command-line sed text-processing

您好,我需要在 300k 行的模式中添加双引号。我正在尝试使用 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;
Run Code Online (Sandbox Code Playgroud)

我需要:

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;
Run Code Online (Sandbox Code Playgroud)

我使用 sed 如下:

sed 's/MSTRG./"MSTRG."/g' filename
Run Code Online (Sandbox Code Playgroud)

但我只能得到:

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;
Run Code Online (Sandbox Code Playgroud)

我试过了:

sed -Ei 's|MSTRG[[:digit:]]+|"&"|g' filename
sed 's/M/"M/; s/$/"/' filename
sed 's/MSTRG.[[:digit:]]+/"MSTRG.[[:digit:]]+"/g' filename
Run Code Online (Sandbox Code Playgroud)

但这些都行不通。

我想知道我是否可以使用 awk,但我对这种语言没有任何技能。

有什么帮助吗?

提前致谢。

ter*_*don 5

为什么要把自己限制在这个特定的基因名称上呢?这是一个更通用的解决方案,它将在第一个之后gene_idtranscript_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;
Run Code Online (Sandbox Code Playgroud)

解释

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

您可以在任意基因名称上使用它,甚至是整个 GTF 文件,它应该可以正常工作。


Cyr*_*rus 4

使用 GNU sed:

sed -E 's/MSTRG[0-9.]+/"&"/g' file
Run Code Online (Sandbox Code Playgroud)

输出:

chr1 StringTie 外显子 191964 192299 1000 - . 基因_id“MSTRG.201”;script_id "MSTRG.201.53"; 外显子号2;
chrY StringTie 外显子 26420508 26420531 1000 + . 基因 ID“MSTRG.49889”;script_id "MSTRG.49889.11"; 外显子号1;

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

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

  • 使用看起来一致的 `;` .... `sed 's/MSTRG.[^;]*/"&"/g'` 可能是一个更短的替代方案...此外,很可能是扩展的正则表达式标志 ` -E` 不需要。 (2认同)