我在bash脚本的for循环中得到了这个:
xpath $f '//bad/objdesc/desc[$i]' > $f.$i.xml
$ i是柜台。
它没有用。
如何在desc元素的括号中正确引用$ i?
感谢。
答案 0 :(得分:2)
改为使用双引号,以便变量得到扩展,而不是按$i
字面处理:
xpath "$f" "//bad/objdesc/desc[$i]" > "$f.$i.xml"
来自bash
manual:
3.1.2.2单引号
用单引号括起字符(''')会保留引号中每个字符的字面值。单引号之间可能不会出现单引号,即使前面有反斜杠也是如此。
3.1.2.3双引号
用双引号括起来的字符('"')会保留引号中所有字符的字面值,除了'$','
’, ‘\’, and, when history expansion is enabled, ‘!’. The characters ‘$’ and ‘
'在双引号中保留其特殊含义(参见Shell Expansions)。反斜杠只有在跟随以下字符之一时才会保留其特殊含义:'$','`','"','\'或换行符。在双引号内,将删除后跟其中一个字符的反斜杠。没有特殊含义的字符前面的反斜杠不做修改。双引号可以在双引号内引用,前面加一个反斜杠。如果启用,将执行历史记录扩展,除非使用反斜杠转义出现在双引号中的“!”。 “!”前面的反斜杠不会被删除。
答案 1 :(得分:0)
对于特定的索引到列表中的情况,这是一种更有效的替代方法。
counter=1
while IFS='' read -r -d $'\x03' line; do
printf '%s' "$line" >"%f.$(( counter++ )).xml"
done < <(xmlstarlet sel -t -m //bad/objdesc/desc -v . -o $'\x03')
这只运行xmlstarlet
(xpath
的一个更强大的替代方法)只有,并将整个值集(甚至它们应该是多行)检索到bash数组中,可以${array[0]}
,${array[1]}
等方式访问它们
需要注意的是,在其内容中包含文字EOT字符的值将在该字符上拆分为多个值。
关于安全的话:
扩展查询参数 - 无论是XPath,SQL还是其他 - 在bash的双引号内打开最多query injection attacks。我们假设您有一个带有客户ID的变量,并且您正在查找帐户余额;如果您使用xpath "//record[customer='$id' and record='$rec']"
,那么可以为$rec
提供字面值的客户也可以通过转发引号来查找属于具有不同ID的客户的内容。
安全的替代方法是使用一种工具,让您以单引号传递查询,并将带外参数传递给--var name="$value"
参数。在具备此功能之前,我无法建议Perl xpath
工具以供一般使用。
如果问题原始海报以外的其他人考虑将xpath
工具与用户提供或不受信任的数据一起使用,请牢记以上内容。