在管道中执行命令

在管道中执行命令

我需要了解为什么我无法执行以下操作。

ls -d /data/VT60000* | xargs -IDIRECTORY find DIRECTORY -type f -iname RJ\*.xml | xargs -IFILE sh -c ' XML=$( xmlstarlet fo -D "FILE" );
EXTRACT=$( xmlstarlet sel -t -c "concat('JD',/root/item1,/root/item2)" <<< "$XML" );
echo '$EXTRACT'; '

我有一堆文件夹,其中包含数千个 XML 文件。我想从这些文件中提取信息,然后操作它们以供以后处理。我通过管道传输它们的原因是因为我想执行多个进程(-P)

第二个 xmlstarlet 无法执行,我不明白为什么。

问题是我怎样才能实现这一目标?获取 $EXTRACT 中的值。

感谢您提前提供的帮助。

答案1

这里的主要问题似乎是您XML在名为 from 的 shell 内分配变量xargs,但您尝试使用主脚本中的变量。这是行不通的,因为子进程无法将变量直接传递给父 shell。

相反,您需要打印出该值,或者在同一 shell 中使用它。

从脚本来看,在我看来你想做的是这样的:

xmlstarlet fo -D "FILE" | xmlstarlet sel -t -c "concat('JD',/root/item1,/root/item2)"

或与sh -c

sh -c 'xmlstarlet fo -D "FILE" | xmlstarlet sel -t -c "concat('\''JD'\'',/root/item1,/root/item2)"'

尽管引用变得很糟糕,所以将其放入另一个脚本或变量中(要么只是字符串,要么是数组中的整个内容)可能是值得的。

另外,我不确定xmlstarlet如果它被多次调用,您想对第一行的输出做什么。


ls /data/VT60000* | xargs您可以使用代替printf "%s\0" * | xargs -0来避免有问题的文件名的问题。

答案2

echo '$EXTRACT'由于单引号使用不正确(单引号不允许替换)和嵌套单引号不正确(单引号内的单引号),因此无法工作。它应该是单引号内的双引号。我无法测试你的代码,所以我写了这个并测试了:

ls -d $HOME | \
   xargs -IDIR find "DIR" -type f -name '*\.conf' | \
   xargs -IFILE sh -c 'l=$(wc -l "FILE"); echo "$l"'

相关内容