如果内容匹配,则替换多行标记内容

时间:2012-07-02 17:33:46

标签: perl replace tags sed awk

我对perl,awk或sed不太熟练,而且我现在一直在网上搜索我的问题的解决方案,但不是很成功。

我想替换

<math> ... </math>

<math>\begin{align} ... \end{align}</math>

如果 ...包含\\。我的问题是<math>标签之间的字符串可以跨越多行。我设法用sed替换一行内的标签,但无法让它运行多行。

任何使用perl,awk或sed的简单解决方案都是非常受欢迎的。非常感谢。

3 个答案:

答案 0 :(得分:1)

为每个标签使用单独的表达式,脚本将不受多线性影响:

sed -e 's,<math>,&\\begin{align},g' -e 's,</math>,&\\end{align},g' 

编辑: 多行awk版本:

awk '/<math>/,/<\/math>/ {
  if (index($0, "<math>")) { 
    a=$0
  } else {
    b = b $0
  }
  if (index($0, "</math>")) {
    if (index(b,"\\\\")) {
      sub("<math>","&\\begin{align}", a)
      sub("</math>","\\end{align}&", b)
    }; 
    print a,b
    a=""
    b=""
  } 
}'

答案 1 :(得分:0)

尝试下一个perl命令。这个怎么运作?它以slurp模式读取内容文件,将其保存在$f变量中,然后在单一模式下添加正则表达式(将新行与.匹配)\begin{regex}\end{regex}如果找到\\ perl -e ' do { $/ = undef; $f = <> }; $f =~ s#(<math>)(.*\\\\.*)(</math>)#$1\\begin{align}$2\\end{align}$3#s; printf qq|%s|, $f ' infile 1}} math 标签之间。

{{1}}

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed ':a;$!{N;ba}
/[\x00\x01\x02]/q1
s/<math>/\x00/g
s/<\/math>/\x01/g
s/\\\\/\x02/g
s/\x00\([^\x01\x02]*\)\x01/<math>\1<\/math>/g
s/\x00/<math>\\begin{align}/g
s/\x01/\\end{align}<\/math>/g
s/\x02/\\\\/g' file