2017-02-28 81 views
2

我想根据上下文与sed转换一个变量字符串。可变字符串转换与sed

string="GAGGTGGGTGGGGAGC" 
echo $string | sed -r 's/G+([AT])/A+\1/g' 

结果是:A+AA+TA+TA+AGC。但我预计:AAAATAAATAAAAAGC

换句话说,我想用一个A或T代替一个未知的Gs片段。我们如何恢复匹配的模式的Gs数量以重用它在替代模式?

+2

'。不幸的是,sed不支持lookaround。 –

+0

很棒!谢谢。对于记录,要使用的命令行是:'echo $ string | perl -pe's/G(?= G * [AT])/ A/g' – retrogenomics

+0

请注意,在这种情况下,建立一个小型状态机来解析是很简单的。如果您需要处理大量数据并定期执行此操作,则可能需要付出额外的努力。另外,如果你有很多字符串需要处理,一定要将它们作为流传递给sed,而不是每次处理一个字符串都调用sed,这会大大减慢处理速度。 – Fred

回答

3

随着SED,使用反向引用和t(测试)命令循环在进一步替换命令的开始,如果置换成功:

$ sed ':a;s/G\([AT]\)\(.*\)/A\1\2/;ta;' <<< "GAGGTGGGTGGGGAGC" 
AAAATAAATAAAAAGC 

它是如何工作的:

  • :aa即将到来的循环标签
  • s:替代命令
  • G\([AT]\):搜索G,然后是AT。第二个字母被捕获,并且将在替换字符串使用反向引用
  • \(.*\)使用:捕获剩余的字符
  • A\1\2:与A接着先前捕获的字符串(AT和剩余的字符)
  • ta取代:如果先前的替代使用`perl`,你可以使用一个像`s/G(?= G * [AT])/ A/g这样的正则表达式来代替脚本来检查脚本的进一步替换
+0

它运作良好,但你能解释背后的逻辑吗? – retrogenomics

+0

请参见[用't'测试](http://www.grymoire.com/Unix/Sed.html#uh-59)。 –

+0

@retrogenomics我添加了一些解释。 – SLePort