sed多行替换搜索

时间:2020-11-05 12:11:52

标签: regex sed replace multiline

我获得了讨厌的旧语法的fortran代码,并想移植到新语法。 我的 sed命令

sed -nr 'N;s/\n\s*\d\D\s*//g' file 

应该找到带编号的换行符,但由于我不知道的原因而无法使用。我已经在这里查看了多个多行sed问题,但仍然无法消除我的误解。据我了解,该命令的工作方式如下:

N                   append next line to pattern space; thus pattern space has two lines with \n in between
s///g               usual search-replace
\n\s*\d\D\s*        matches a newline followed by \s*, a digit, a non-digit and a \s* again

源代码看起来像

   if(condition) then 
         call func1(v1, v2, v3, v4
     1              ,v5,v6,v7)
      else
         call func2(v1, v2, v3, v4
     1              ,v5,v6,v7)
      endif
call MPI_BCAST(num(1),1,MPI_DOUBLE_PRECISION
     1     ,masterid,comm,mpinfo)
21      format(' text',2x,f10.5)

,并应转换为目标代码

   if(condition) then 
         call func1(v1, v2, v3, v4,v5,v6,v7)
      else
         call func2(v1, v2, v3, v4,v5,v6,v7)
      endif
call MPI_BCAST(num(1),1,MPI_DOUBLE_PRECISION,masterid,comm,mpinfo)
21      format(' text',2x,f10.5)

2 个答案:

答案 0 :(得分:2)

这可能对您有用(GNU sed):

sed -E ':a;N;s/\n\s*[0-9]\s*([^0-9])/\1/;ta;P;D' file

使用2行窗口浏览文件。

如果第二行以一些空格或无空格开头,后跟一个数字,然后是一些空格或无空格,后跟一个非数字,则用非数字代替并重复。否则,打印窗口的第一行,然后将其删除并重复。

答案 1 :(得分:1)

这是perl的一种可能的解决方案,适用于给定的样本输入:

perl -0777 -pe 's/\n\h*\d\h*(?=,)//g'
  • -0777将整个输入作为单个字符串
  • \n\h*\d\h*匹配换行符,后跟可选的水平空格,后跟数字字符,再跟可选的水平空格
    • (?=,)仅在此类匹配后有逗号字符时才匹配...否则,您需要告诉如何不匹配21 format(' text',2x,f10.5)

使用GNU sed,但是我对这些命令的理解不足以使人确信:

sed -E 'N; s/\n\s*[0-9]\s*,/,/; P; D'

来自GNU sed manual

P 打印出部分图案空间,直到第一行。

D 如果模式空间不包含换行符,请像发出d命令一样开始正常的新循环。否则,删除模式空间中的文本,直到第一行换行,然后使用结果模式空间重新开始循环,而无需读取新的输入行。