Sed:查找并替换环绕到下一行的模式

Sed:查找并替换环绕到下一行的模式

我想查找并替换一个模式,但它也环绕到下一行,我需要找到某种方法来处理这个问题

看起来像这样的东西:

....tr("Changes to output mappings will be deleted. "
"There is no undo available. Do you want to continue?"));

变成类似的东西

...."Changes to output mappings will be deleted. "
"There is no undo available. Do you want to continue?");

(...是以前的代码)

到目前为止,我的代码如下(适用于单行,但不适用于换行的文本/代码):

sed -i 's/tr(\([^)]*\))/\1/I' $file_t

我该怎么办呢?

答案1

tr(对于命令始终分布在两行上的情况,请尝试:

$ sed  '/tr(/N; s/tr(\([^)]*\))/\1/I' "$file_t"
...."Changes to output mappings will be deleted. "
"There is no undo available. Do you want to continue?");

这里唯一的变化是添加了/tr(/N.对于任何匹配 的行tr(,它会读入下一行并将其添加到模式空间 ( N)。

要就地更改文件,请使用-i

sed  -i.bak '/tr(/N; s/tr(\([^)]*\))/\1/I' "$file_t"

更强大的版本

如果tr(...)命令可能出现在一行、两行或多于两行,我们需要稍微改变一下逻辑:

sed  '/tr(/{ :a; s/tr(\([^)]*\))/\1/I; t; N; ba}' filename

这会查找包含 的行tr(。对于任何此类行,{...}都会执行大括号 , 中的命令。对于这些行,首先仅在该行上尝试替换。如果发生替换,则该t命令告诉 sed 我们已经完成了这一行。如果没有发生,意味着没有结束),则在 ( ) 中读取下一行N,并且 sed 分支回标签a( ba) 并再次尝试替换。重复此操作,直到读入足够的行以找到).

例如,这是一个tr(...)分布在一行、两行和三行的文件:

$ cat filename
tr("abc");
....tr("Changes to output mappings will be deleted. "
"There is no undo available. Do you want to continue?"));
tr("one
two
three");

这是输出:

$ sed  '/tr(/{ :a; s/tr(\([^)]*\))/\1/I; t; N; ba}' filename
"abc";
...."Changes to output mappings will be deleted. "
"There is no undo available. Do you want to continue?");
"one
two
three";

tr(...)和之间的区别Ptr(...)

为了确保我们只替换tr而不是替换PtrStr,我们需要确保tr从单词边界开始。对于 GNU sed (Linux),字边界表示为\b

sed  '/\btr(/{ :a; s/\btr(\([^)]*\))/\1/I; t; N; ba}' filename

使用 BSD (OSX) sed,下列可能有效:

sed  '/[[:<:]]tr(/{ :a; s/[[:<:]]tr(\([^)]*\))/\1/I; t; N; ba}' filename

相关内容