调用shell函数,将并行的带有引用的文件名列表作为输入

问题描述 投票:0回答:2

使用重击。

我有一个导出的外壳函数,我想应用于许多文件。

通常我会使用xargs,但是这样的语法(请参见here)太难看了,无法使用。

...... | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}

在那个讨论中,parallel的语法更简单:

..... | parallel -P 10 echo_var {}

现在,我遇到了以下问题:我要对其应用功能的文件列表是一行文件的列表,每个文件都用引号引起来并用空格分隔:"file 1" "file 2" "file 3"

我如何将此用引号引起来的空格分隔的列表输入parallel

我可以使用echo复制列表进行测试。

例如

echo '"file 1" "file 2" "file 3"'|parallel -d " " my_function {}

但是我无法使它正常工作。

我该如何解决?

bash xargs gnu-parallel
2个回答
0
投票

我该如何解决?

您必须选择一个唯一的分隔符。

echo 'file 1|file 2|file 3' | xargs -d "|" -n1 bash -c 'my_function "$@"' --
echo 'file 1^file 2^file 3' | parallel -d "^" my_function

最安全的方法是使用零字节作为分隔符:

echo -e 'file 1\x00file 2\x00file 3' | xargs -0 ' -n1 bash -c 'my_function "$@"' --
printf "%s\0" 'file 1' 'file 2' 'file 3' | parallel -0 my_function

最好是将元素存储在bash数组中,并使用零分隔流对其进行处理:

files=("file 1" "file 2" "file 3")
printf "%s\0" "${files[@]}" | xargs -0 -n1 bash -c 'my_function "$@"' --
printf "%s\0" "${files[@]}" | parallel -0 my_function

请注意,空数组将在不带任何参数的情况下运行该函数。有时最好在输入为空时使用-r --no-run-if-empty选项不运行该函数。 --no-run-if-emptyparallel支持,并且是xargs中的gnu扩展名(BSD和OSX上的xargs没有--no-run-if-empty)。

注意:xargs默认情况下解析'"\。这就是为什么以下可能并会起作用的原因:

echo '"file 1" "file 2" "file 3"' | xargs -n1 bash -c 'my_function "$@"' --
echo "'file 1' 'file 2' 'file 3'" | xargs -n1 bash -c 'my_function "$@"' --
echo 'file\ 1 file\ 2 file\ 3' | xargs -n1 bash -c 'my_function "$@"' --

这可能会导致一些奇怪的事情,因此请记住,几乎总是将-d选项指定为xargs

$ # note \x replaced by single x
$ echo '\\a\b\c' | xargs
\abc
$ # quotes are parsed and need to match
$ echo 'abc"def' | xargs
xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option
$ echo "abc'def" | xargs
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

[xargs是随处可见的便携式工具,而parallel是GNU程序,必须单独安装。


0
投票

您有几种选择:

(echo "file 1";
 echo "file 2";
 echo "file 3") | parallel my_function

(echo '"file  1" "file  2" "file  3"') |
    parallel eval my_function

自20190722起,您可以使用uq(取消引号),这将告诉GNU Parallel不要引用此替换字符串:

(echo '"file  1" "file  2" "file  3"') |
    parallel  my_function {=uq=}

如果您将它们放在数组中:

parallel my_function ::: "${files[@]}"
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.