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

Regex Shell:sed-替换特定数字范围中的文本,regex,bash,shell,replace,sed,Regex,Bash,Shell,Replace,Sed,我有以下问题: sed-es/[theText][someNumber]/$var2/ 我在课文旁边有一个数字。 我需要执行以下操作-如果数字介于5和20之间,请将字符串替换为$var2,否则什么也不做。有没有可能在sed中直接执行此操作而不使用循环?我试过像课文[5-20]2这样的结构,但没有成功。谢谢 由于sed不懂算术,因此sed不是这里理想的工具。但是,以下内容将满足您的要求: sed -Ee "s/some text ([5-9]|1[0-9]|20)$/$var2/" 或者,如果您

我有以下问题:

sed-es/[theText][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 to rescue

$ 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

我开始拆分字符串和数字,但使解决方案变得混乱:

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
我仍然不喜欢它的主要原因是因为它很难阅读。 您可以引入一个额外变量number=${str${matchstring}},只是为了在根据限制测试数字时更易于阅读。

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

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

将高、低值更改为所需的任何范围。我认为这可能比awk脚本更具可读性/可维护性,但awk也可以处理这一点

谢谢你的回答。你一般建议做什么?因为间隔是动态的,所以我使用一个变量作为第一个数字,5-20只是为了说明。可能是1-20甚至18-20。我想使用循环重复20-N次,在每次迭代中替换范围内的一个数字。注意:不要担心安全性,它是一个仅供内部使用的脚本:@melonsvk Awk可能是用于此目的的正确工具:它可以进行替换,并且理解数学。值得注意的是,BSD sed中的-E标志相当于GNU sed中的-r标志。@miken32 Yes。但请注意,GNU的现代版本支持将-E作为-r的同义词。此外,有传言说-E将成为POSIX的选择。
HIGH=350 
LOW=100 
IFS=$(echo -en "\n\b") && for a in $(< yourfile.txt); do 
VAR=$(grep -o "[0-9]*$" <<< "${a}")
((${VAR} < ${HIGH})) && ((${VAR} > ${LOW})) && sed "s/${a}/${var2}/"
done