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

时间:2015-11-09 20:24:09

标签: regex bash shell replace sed

我遇到以下问题:

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

我旁边有一个数字。 我需要做以下 - 如果数字在5到20之间,用$ var2替换字符串,否则什么都不做。是否有可能在不使用循环的情况下直接在sed中执行此操作?我尝试过像 theText [5-20] 2 这样的结构,但它没有用。谢谢!

4 个答案:

答案 0 :(得分:0)

因为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命令是一个安全问题,因为它可以执行任意命令。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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时更容易阅读。

答案 3 :(得分:0)

您可以使用Bashgrep获取数字部分并在使用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 

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