使用重击。
我有一个导出的外壳函数,我想应用于许多文件。
通常我会使用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 {}
但是我无法使它正常工作。
我该如何解决?
我该如何解决?
您必须选择一个唯一的分隔符。
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-empty
受parallel
支持,并且是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程序,必须单独安装。
您有几种选择:
(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[@]}"