Sed 查找和替换表达式适用于文字但不适用于变量插值
Sed find and replace expression works with literal but not with variable interpolation
对于以下 MVCE:
echo "test_num: 0" > test.txt
test_num=$(grep 'test_num:' test.txt | cut -d ':' -f 2)
new_test_num=$((test_num + 1))
echo $test_num
echo $new_test_num
sed -i "s/test_num: $test_num/test_num: $new_test_num/g" test.txt
cat test.txt
echo "sed -i "s/test_num: $test_num/test_num: $new_test_num/g" test.txt"
sed -i "s/test_num: 0/test_num: 1/g" test.txt
cat test.txt
输出
0 # parsed original number correctly
1 # increment the number
test_num: 0 # sed with interpolated variable, does not work
sed -i s/test_num: 0/test_num: 1/g test.txt # interpolated parameter looks right
test_num: 1 # ???
为什么 sed -i "s/test_num: $test_num/test_num: $new_test_num/g" test.txt
没有产生预期的结果,而 sed -i "s/test_num: 0/test_num: 1/g" test.txt
在上面的例子中工作得很好?
如评论中所述,${test_num}
中有一个白色的space。因此,在您的 sed
中,冒号和变量之间不应有空 space。
此外,我想您应该用花括号 {}
将变量括起来以提高可读性。
sed "s/test_num:${test_num}/test_num: ${new_test_num}/g" test.txt
test_num: 1
如果您只想要 ${test_num}
中的数字,您可以尝试这样的操作:
grep 'test_num:' test.txt | awk -F ': ' '{print }'
awk
允许指定多于 1 个字符的分隔符。
除了grep|cut
你还可以使用sed
.
#! /bin/bash
exec <<EOF
test_num: 0
EOF
grep 'test_num:' | cut -d ':' -f 2
exec <<EOF
test_num: 0
EOF
sed -n 's/^test_num: //p'
在 sed
中使用正则表达式替换时 $
有特殊含义。
建议重建您的 sed
命令段如下:
sed -i 's/test_num: '$test_num'/test_num: '$new_test_num'/g' test.txt
其他选项,使用echo
命令扩展sed
命令中的变量。
sed_command=$(echo "s/test_num:${test_num}/test_num: ${new_test_num}/g")
sed -i "$sed_command" test.txt
对于以下 MVCE:
echo "test_num: 0" > test.txt
test_num=$(grep 'test_num:' test.txt | cut -d ':' -f 2)
new_test_num=$((test_num + 1))
echo $test_num
echo $new_test_num
sed -i "s/test_num: $test_num/test_num: $new_test_num/g" test.txt
cat test.txt
echo "sed -i "s/test_num: $test_num/test_num: $new_test_num/g" test.txt"
sed -i "s/test_num: 0/test_num: 1/g" test.txt
cat test.txt
输出
0 # parsed original number correctly
1 # increment the number
test_num: 0 # sed with interpolated variable, does not work
sed -i s/test_num: 0/test_num: 1/g test.txt # interpolated parameter looks right
test_num: 1 # ???
为什么 sed -i "s/test_num: $test_num/test_num: $new_test_num/g" test.txt
没有产生预期的结果,而 sed -i "s/test_num: 0/test_num: 1/g" test.txt
在上面的例子中工作得很好?
如评论中所述,${test_num}
中有一个白色的space。因此,在您的 sed
中,冒号和变量之间不应有空 space。
此外,我想您应该用花括号 {}
将变量括起来以提高可读性。
sed "s/test_num:${test_num}/test_num: ${new_test_num}/g" test.txt
test_num: 1
如果您只想要 ${test_num}
中的数字,您可以尝试这样的操作:
grep 'test_num:' test.txt | awk -F ': ' '{print }'
awk
允许指定多于 1 个字符的分隔符。
除了grep|cut
你还可以使用sed
.
#! /bin/bash
exec <<EOF
test_num: 0
EOF
grep 'test_num:' | cut -d ':' -f 2
exec <<EOF
test_num: 0
EOF
sed -n 's/^test_num: //p'
在 sed
中使用正则表达式替换时 $
有特殊含义。
建议重建您的 sed
命令段如下:
sed -i 's/test_num: '$test_num'/test_num: '$new_test_num'/g' test.txt
其他选项,使用echo
命令扩展sed
命令中的变量。
sed_command=$(echo "s/test_num:${test_num}/test_num: ${new_test_num}/g")
sed -i "$sed_command" test.txt