如何使用sed将匹配的模式替换为行的开头?

时间:2019-06-28 19:03:29

标签: sed

我有一个看起来像这样的文件:

254529  ANN=C|blabla,T|blabla,A|blabla
254540  ANN=T|blabla,G|blabla,C|blabla
254586  ANN=TTGG|blabla,A|blabla

我想用逗号替换文件中的逗号,然后在行首添加数字。

我文件中的

blabla实际上是很长的文字,出于可读性考虑,我在此处进行了更改。每个blabla都不同。

我尝试了以下操作,但它仅替换了该行中的最后一个逗号。

sed -e 's/^\(.*\)\(\t.*\),/\1\2,\1\t/g' file

这是我得到的:

254529  ANN=C|blabla,T|blabla,254529    A|blabla
254540  ANN=T|blabla,G|blabla,254540    C|blabla
254586  ANN=TTGG|blabla,254586  A|blabla

虽然我想获得这个:

254529  ANN=C|blabla,254529    T|blabla,254529    A|blabla
254540  ANN=T|blabla,254540    G|blabla,254540    C|blabla
254586  ANN=TTGG|blabla,254586  A|blabla

使用sed可以做到吗?

谢谢

1 个答案:

答案 0 :(得分:0)

使用sed

问题在于,g不会进行全局替换。简单的解决方案是重复替换次数,只要有逗号即可。像这样:

$ sed ':a; s/^\(.*\)\(\t.*\),/\1\2\n\1\t/; ta; s/\n/,/g' file
254529  ANN=C|blabla,254529     T|blabla,254529 A|blabla
254540  ANN=T|blabla,254540     G|blabla,254540 C|blabla
254586  ANN=TTGG|blabla,254586  A|blabla

工作原理:

  • :a

    这将创建标签a

  • s/^\(.*\)\(\t.*\),/\1\2\n\1\t/

    这将执行您的替换(稍作修改)。由于.*是“贪婪的”,因此它将在该行的最后一个逗号处执行它。

    由于.*是“贪婪的”,因此是否应用g修饰符并不重要:只会匹配最后一个逗号,并且只会执行一个替换。

    与您的命令的不同之处在于,在输出中,逗号用换行符代替。这样一来,我们就不会尝试在同一逗号上再次重复替换。

  • ta

    如果最后一次替换成功,则跳回到标签a。

  • s/\n/,/g

    将所有换行符转换回逗号。

使用awk

$ awk -F'\t' '{gsub(/,/, ","$1"\t")} 1' file
254529  ANN=C|blabla,254529     T|blabla,254529 A|blabla
254540  ANN=T|blabla,254540     G|blabla,254540 C|blabla
254586  ANN=TTGG|blabla,254586  A|blabla