使用全包通配符查找和替换文本 [英] Find and replace text with all-inclusive wild card

查看:340
本文介绍了使用全包通配符查找和替换文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  foo和更多
东西
各种东西
可变行数
带酒吧
东西我要保留
更多东西我要保留
这些换行符是重要的

我想替换foo和bar之间的所有内容,以便获得:

<$ p $
$ f




$ b $这些换行符是重要的

在另一个线程中推荐我试过:
sed -e'/ ^ foo /,/ ^ bar / { / ^ foo / b; / ^ bar / {i testtext'-e'b}; d}'file.txt



一个更通用的解决方案来查找和替换 foo bar 之间的所有内容,绝对不管它是什么?

解决方案

您可以使用以下 sed 脚本:


$ b $替换为:

$ p $ #检查 foo
/ \bfoo\b / {
#定义一个标签a
:a
#如果该行不包含bar
/ \bbar\b /!{
#获取输入的下一行并将
#追加到模式缓冲区
N
#转回到标签a
ba

#替换foo和bar之间的所有内容
s / \(\bfoo\)\ b。* \b\(bar\b \)/ \ 1TEST DATA\2 /
}



  sed -f extract.sed input.file 

输出:


$ b

  fooTEST DATAbar 
东西我想保留
更多的东西我想保留
这些换行是重要的

如果你想使用shell脚本来传递开始和结束分隔符,你可以这样做(注释为简洁起见):

 #!/ bin / bash 

begin =foo
end =bar

replacement =Hello world

sed -r'/ \b'$ begin'\b / {
:a; / \b'$ end'\b /!{
N; ba
}
s /(\b'$ begin')\b。* \ b(''$ end''\b)/ \'''$ replacement''\ 2 /
}'input.file



以上的工作只要 $ start $ end 将不包含正则表达式特殊字符,正确地转义它们使用以下代码:

 #!/ bin / bash 

begin =foo
end =bar
replace =Hello \ 1world

#在正则表达式中使用的转义变量
beginEsc = $(sed's / [^^] / [&安培;] /克; s \ ^ / \\\ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ / \\'^ \\ ^ / g'<<<$ end)
replaceEsc = $(sed's / [& / \] / \\\& / $ b $ {

$ b $ a $ / $'$'$'$' \\ b'$ endEsc'\b /!{
N; ba
}
s /(\ b'$ beginEsc')\ b。* \b (''$ endEsc''\b)/ \ 1'$ replaceEsc'\ 2 /
}input.file


I have a file like this:

foo and more
stuff
various stuff
variable number of lines
with a bar
Stuff I want to keep
More stuff I want to Keep
These line breaks are important

I want to replace everything between foo and bar so that I get:

foo testtext bar
Stuff I want to keep
More stuff I want to Keep
These line breaks are important

as recommended in another thread I tried: sed -e '/^foo/,/^bar/{/^foo/b;/^bar/{i testtext' -e 'b};d}' file.txt

Is there a more general-purpose solution to find and replace everything between foo and bar, absolutely no matter what it is?

解决方案

You can use the following sed script:

replace.sed:

# Check for "foo"
/\bfoo\b/    {   
    # Define a label "a"
    :a  
    # If the line does not contain "bar"
    /\bbar\b/!{
        # Get the next line of input and append
        # it to the pattern buffer
        N
        # Branch back to label "a"
        ba
    }   
    # Replace everything between foo and bar
    s/\(\bfoo\)\b.*\b\(bar\b\)/\1TEST DATA\2/
}

Call it like this:

sed -f extract.sed input.file

Output:

fooTEST DATAbar
Stuff I want to keep
More stuff I want to Keep
These line breaks are important


If you want to pass the begin and ending delimiter using a shell script you can do it like this (comments removed for brevity):

#!/bin/bash

begin="foo"
end="bar"

replacement=" Hello world "

sed -r '/\b'"$begin"'\b/{
    :a;/\b'"$end"'\b/!{
        N;ba
    }
    s/(\b'"$begin"')\b.*\b('"$end"'\b)/\1'"$replacement"'\2/
}' input.file


The above works as long as $start and $end won't contain regex special characters, to escape them properly use the following code:

#!/bin/bash

begin="foo"
end="bar"
replace=" Hello\1world "

# Escape variables to be used in regex
beginEsc=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<<"$begin")
endEsc=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<<"$end")
replaceEsc=$(sed 's/[&/\]/\\&/g' <<<"$replace")

sed -r '/\b'"$beginEsc"'\b/{
    :a;/\b'"$endEsc"'\b/!{
        N;ba
    }
    s/(\b'"$beginEsc"')\b.*\b('"$endEsc"'\b)/\1'"$replaceEsc"'\2/
}' input.file

这篇关于使用全包通配符查找和替换文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆