在两个模式之间替换字符串

时间:2020-05-06 12:02:30

标签: shell

原始字符串:allow from 1.1.1.1 9.9.9.9 2.2.2.2

我想用9.9.9.9代替5.5.5.5,例如allow from 1.1.1.1 5.5.5.5 2.2.2.2

目标是替换allow from 1.1.1.12.2.2.2之间的任何字符串

3 个答案:

答案 0 :(得分:0)

像这样吗?

new="5.5.5.5" perl -pe 's/(allow from 1.1.1.1 ).*?( 2.2.2.2)/$1$ENV{new}$2/' $YOUR_FILE

给出一个包含

的文件
allow from 1.1.1.1 9.9.9.9 2.2.2.2
allow from 1.1.1.1 x 2.2.2.2
allow from 1.1.1.1 3.3.3 2.2.2.2

它将输出:

allow from 1.1.1.1 5.5.5.5 2.2.2.2
allow from 1.1.1.1 5.5.5.5 2.2.2.2
allow from 1.1.1.1 5.5.5.5 2.2.2.2

它用在perl命令前面定义的变量$new的内容替换了“从1.1.1.1允许”到“ 2.2.2.2”之间的所有内容。

如果要确保只替换由点分隔的4位数字,可以将正则表达式中的.*?替换为\d\.\d\.\d\.\d。如果这些是IPv4地址,则还可以使用\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}或更严格的[\d\.]{7,15}(7到15个字符,所有点或数字)。

如果要“就地”执行操作,而不是将结果打印到STDOUT,则可以添加-i.bak作为第一个选项。首先将“ $ YOUR_FILE”备份到“ $ YOUR_FILE.bak”

答案 1 :(得分:0)

我将假设该行的其余部分始终是allow from 1.1.1.1,位于您要修改的部分之前,2.2.2.2,位于您要修改的部分之后。试试:

string1="allow from 1.1.1.1 9.9.9.9 2.2.2.2"
new=5.5.5.5
string2=$(echo "$string1" | sed "/^\(allow from 1\.1\.1\.1\) .* \(2\.2\.2\.2\)$/s//\1 $new \2/")

如果不确定始终使用1.1.1.1还是2.2.2.2,则必须相应地修改正则表达式,这很简单,例如:

string2=$(echo "$string1" | sed "/^\(allow from [^ ]*\) .* \([^ ]*\)$/s//\1 $new \2/")

答案 2 :(得分:0)

我将使用awk,并将IP地址作为参数传递:

awk -v start="1.1.1.1" -v end="2.2.2.2" -v repl="5.5.5.5" '
    /allow from/ && $3 == start && $5 == end {$4 = repl}
    {print}
' file

如果您需要就地保存该文件,则有几种选择:

awk ... file > tmpfile && mv tmpfile file
awk ... file | sponge file                   # requires the `moreutils` package
awk -i inplace -v ... file                   # requires GNU awk
相关问题