我有以下问题:
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
时更容易阅读。
您可以使用Bash
和grep
来获取数字部分并在使用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
也可以处理此问题。