sed 多行搜索替换
sed multiline search-replace
我得到了令人讨厌的旧语法的 Fortran 代码,想移植到新语法。
我的 sed
命令
sed -nr 'N;s/\n\s*\d\D\s*//g' file
应该可以找到带编号的换行符,但由于我不知道的原因而不起作用。我已经在这里查看了许多 multiline-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)
这是一种适用于给定样本输入的 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 Print out the portion of the pattern space up to the first newline.
D If pattern space contains no newline, start a normal new cycle as if the d command was issued. Otherwise, delete text in the pattern space up to the first newline, and restart cycle with the resultant pattern space, without reading a new line of input.
这可能适合您 (GNU sed):
sed -E ':a;N;s/\n\s*[0-9]\s*([^0-9])//;ta;P;D' file
使用第 2 行遍历文件 window。
如果第二行以一些白色或没有白色 space 开头,后跟一个数字,然后是更多或没有白色 space,然后是 non-digit,请替换此行通过 non-digit 并重复。否则打印 window 的第一行,然后删除它并重复。
我得到了令人讨厌的旧语法的 Fortran 代码,想移植到新语法。
我的 sed
命令
sed -nr 'N;s/\n\s*\d\D\s*//g' file
应该可以找到带编号的换行符,但由于我不知道的原因而不起作用。我已经在这里查看了许多 multiline-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)
这是一种适用于给定样本输入的 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 Print out the portion of the pattern space up to the first newline.
D If pattern space contains no newline, start a normal new cycle as if the d command was issued. Otherwise, delete text in the pattern space up to the first newline, and restart cycle with the resultant pattern space, without reading a new line of input.
这可能适合您 (GNU sed):
sed -E ':a;N;s/\n\s*[0-9]\s*([^0-9])//;ta;P;D' file
使用第 2 行遍历文件 window。
如果第二行以一些白色或没有白色 space 开头,后跟一个数字,然后是更多或没有白色 space,然后是 non-digit,请替换此行通过 non-digit 并重复。否则打印 window 的第一行,然后删除它并重复。