为什么以下不起作用?
INTERNAL_NUM=$(grep -E '\s*internal_num\s*=' file.xml |sed -E 's/internal_num\s*=\s*([0-9]\+)/\1/')
echo "$INTERNAL_NUM"
我想打印出实际的数字,但它打印:
internal_num = 1234
该grep
命令打印出来internal_num = 1234
,所以该部分没问题。这是sed
不起作用的管道。
答案1
如果你有 GNU grep,你可以写
grep -oP '\binternal_num\s*=\s*\K\d+' file.xml
但您不应该使用正则表达式来解析 XML。也许你需要这样的东西
$ echo '
<root>
<tag>
<tag>
<wanted internal_num="1234" />
<wanted internal_num = "5678" />
</tag>
</tag>
</root>
' | xmlstarlet sel -t -v '//@internal_num' -n
1234
5678
请显示您的输入文件。
答案2
不同的工具和给定工具的实现/版本支持不同的正则表达式语法。
为了便于移植,您可以限制自己使用 POSIX 功能集:
s=[[:space:]]
sed -n "s/^\(.*$s\)\{0,1\}internal_num$s*=$s*\([0-9]\{1,\}\).*/\2/p"
(假设每行只出现一次)
如果您知道您只会在grep
支持GNU-o
和(对于类似 perl 的正则表达式)的系统上运行它,您可以这样做:-P
grep
grep -Po '(?<!\S)internal_num\s*=\s*\K\d+'
答案3
您正在使用扩展正则表达式,但仍然转义\+
,因此它会查找文字加号并且不会调用替换。
尝试,
INTERNAL_NUM=$(grep -E '\s*internal_num\s*=' file.xml |sed -E 's/internal_num\s*=\s*([0-9]+)/\1/')
echo "$INTERNAL_NUM"
测试用例(在 GNU sed V4.2.1 上测试):
$ echo "internal_num = 1234" | sed -E 's/internal_num\s*=\s*([0-9]\+)/\1/'
internal_num = 1234
$ echo "internal_num = 1234" | sed -E 's/internal_num\s*=\s*([0-9]+)/\1/'
1234
正如其他答案提到的(并详细解释),您应该认真考虑不使用正则表达式来解析 XML。