Shell:sed-替换特定数字范围内的文本



我有以下问题:

sed-e"s/[Text][someNumber]/$var2/"

我在课文旁边有一个号码。我需要执行以下操作——如果数字在5到20之间,请将字符串替换为$var2,否则不执行任何操作。有没有可能在sed中直接执行此操作而不使用循环?我尝试过类似于文本[5-20]2的结构,但没有成功。谢谢

因为sed不懂算术,所以sed不是理想的工具。然而,以下内容将满足您的要求:

sed -Ee "s/some text ([5-9]|1[0-9]|20)$/$var2/"

或者,如果你想坚持使用基本的正则表达式:

sed -e "s/some text ([5-9]|1[0-9]|20)$/$var2/"

以上内容查找文本,后跟一个空格,后跟[5-9]1[0-9]20中的一个,后跟行的末尾$

由于sed不懂数学,因此没有办法指定像5-20这样的数字范围。

请确保您信任var2的来源。将$var2放入这样的sed命令中是一个安全问题,因为它可以执行任意命令。

awk前往救援!

$ awk '{match($0,/some text ([0-9]*)/,a); 
        if(a[1]+0>5 && a[1]+0<20) 
            sub(/some text/,"replacement")}1' << EOF
> some text 100
> some text 10
> EOF

将打印

some text 100
replacement 10

我开始拆分字符串和数字,但让解决方案变得一团糟:

lower=4
upper=88
matchstring="MyText"
echo "Example testing substring MyText followed by number 4 until 88"
read -p "Give your teststring "  str
if [[ ${str} = ^${matchstring}* ]]; then
    echo "Nope, no match with ${matchstring}"
else
    echo "Matching ${str#${matchstring}}"
    if [[ "${str#${matchstring}}" =~ ^[0-9]+$ ]]; then
       echo "it is a number..."
       if [ ${str#${matchstring}} -ge ${lower} ] &&
          [ ${str#${matchstring}} -le ${upper} ]; then
          echo "Bingo !"
       else
          echo "Not in range (${lower},${upper})"
       fi
    else
       echo "No number"
    fi
fi

但是这个脚本可以通过结合前两个测试来改进:

lower=4
upper=88
matchstring="MyText"
echo "Example testing substring MyText followed by number 4 until 88"
read -p "Give your teststring "  str
if [[ ${str} =~ ^${matchstring}[0-9]+$ ]]; then
    echo "Nope, You should use ${matchstring}123"
else
    if [ ${str#${matchstring}} -ge ${lower} ] &&
       [ ${str#${matchstring}} -le ${upper} ]; then
       echo "Bingo !"
    else
       echo "Not in range (${lower},${upper})"
    fi
fi

我仍然不喜欢它的主要原因是它很难阅读
您可以引入一个额外的变量theNumber=${str#${matchstring}},只是为了在根据限制测试theNumber时更容易阅读。

您可以使用Bashgrep来获取数字部分并在使用sed进行替换之前对其进行测试:

HIGH=350 
LOW=100 
IFS=$(echo -en "nb") && for a in $(< yourfile.txt); do 
VAR=$(grep -o "[0-9]*$" <<< "${a}")
((${VAR} < ${HIGH})) && ((${VAR} > ${LOW})) && sed "s/${a}/${var2}/"
done 

将HIGH、LOW值更改为您想要的任何范围。我认为这可能比awk脚本更可读/更可维护,但awk也可以处理此问题。

最新更新