假设我们有这个简单的 xmlstarlet 脚本:
find . -iname '*.xml' | xargs xmlstarlet sel -N z="abc.com/article/1.0/" \
-t -m "/z:ad" -i "/*/z:status='PUBLIC'" -v "/*/z:id" -b -n | grep -v ^$
这只是遍历所有 XML 文件(从我执行此脚本的目录开始)并打印出 status=PUBLIC 的记录 ID。
现在我想查找另一个文件中的另一个值,并且该文件具有简单路径
/path/ID.xml
我怎样才能做到这一点?
ChatGPT告诉我这个解决方案,我尝试了几次迭代,没有成功。
find . -iname '*.xml' | xargs xmlstarlet sel -N z="abc.com/article/1.0/" \
-t -m "/z:ad" -i "/*/z:status='PUBLIC'" -v "/*/z:id" -o ',' \
--var name="$(xmlstarlet sel -N z="abc.com/article/1.0/" -t -v '/*/z:name' /PATH/TO/SECOND/FILE.xml)" \
-v '$name' -b -n | grep -v ^$
它不会抛出任何错误,但不会打印第二个文件中的 name 值:
123412341234,
838373847387,
828278388222,
如何使用单行命令来实现这一点?我不想执行脚本。
我真幸运!没有任何数据可供查看,我可以随意猜测,但有些事情 像下面这样应该有效:
# shellcheck shell=sh disable=SC2016
find . -type f -iname '*.xml' -exec xmlstarlet select \
-N z='abc.com/article/1.0/' --text \
-t --var ofs -o ',' -b \
--var ors -n -b \
--var infnm -f -b \
-m '/*[z:status="PUBLIC"]/z:id' \
--var pubid='.' \
--var pubnm='document("/path/ID.xml")/*[z:id=$pubid]/z:name' \
-v 'concat($infnm,$ofs,$pubid,$ofs,$pubnm,$ors)' \
{} +
xargs
可以调用时,为什么还要麻烦 grep
和 find
xmlstarlet select
具有与命令一样多的文件名 ({} +
)
线可以容纳(select --help
说[ <xml-file> ... ]
,回忆一下),
并根据需要重复status="PUBLIC"
状况document()
函数
在外部 XML 文件中查找当前 PUBLIC
id 的名称concat
函数输出
一条记录select
的 -T
(又名 --text
)明文选项
输出ofs
和 ors
保存输出字段/记录
分隔符,infnm
当前输入文件/URL 的名称
(inputFile
是预定义的,但未记录)