根据这个问题,我现在能够更新多个 XML 中的特定变量。
但是,它们都有很多(不必要的)空格,xmllint 将它们全部删除。我现在修改了 50 行,这使得在查看 git diff 时很难看出功能差异。有没有办法让 xmllint 不这样做而只更改我感兴趣的值? (我试图看一下 xmllint 的 man,但没有找到任何看起来像这样的选项)
示例: 原始文件:
<target_tags>
<target_tag name="my_tag1" default="old_value1" />
<target_tag name="my_tag2" default="old_value2" />
<target_tag name="my_tag3" default="old_value3" />
</target_tags>
xmllint 命令:
xmllint --shell /tmp/tmp.xml << EOF
> cd //target_tag[@name="my_tag1"]/@default
> set new_value
> save
> bye
> EOF
/ > default > default > default >
修改文件:
<target_tags>
<target_tag name="my_tag1" default="new_value"/>
<target_tag name="my_tag2" default="old_value2"/>
<target_tag name="my_tag3" default="old_value3"/>
</target_tags>
使用 xmllint 的一个可能的解决方案是按原样输出行,直到找到所需的值
needle='name="my_tag1"'
new_value="new_value1"
while IFS=$'\n' read line; do
if ! grep -q "$needle" <<<"$line";then
# target line not found
echo "$line"
else
ele=$(xmllint --xpath "//target_tag[@$needle]" tmp.xml)
temp_file=$(mktemp)
# save fake xml doc to a temp file
echo -e "<root>\n$line\n</root>" > $temp_file
printf "%s\n" "cd //target_tag[@$needle]/@default" "set $new_value" 'save' 'bye' | xmllint --shell $temp_file >/dev/null
grep "$needle" $temp_file
rm $temp_file
fi
done < tmp.xml
仅更改已修改的行
<target_tags>
<target_tag name="my_tag1" default="new_value"/>
<target_tag name="my_tag2" default="old_value2" />
<target_tag name="my_tag3" default="old_value3" />
</target_tags>