我尝试使用bash脚本中的substring提取与GNU并行混合。但是下面的代码(从更复杂的情况下简化)会产生错误的结果。
#!/bin/bash
function foo(){
echo "${1:0:1} ${1:1:1}" # substring extraction
}
function bar(){
IFS=', ' read -r -a array <<< "${1}" # string to array conversion
echo "${array[0]} ${array[1]}"
}
export -f foo
export -f bar
values=( '12' '34' )
parallel echo $(foo {} ) ::: "${values[@]}"
# produces wrong output...
# {} 12
# {} 34
parallel echo $(bar {} ) ::: "${values[@]}"
# produces wrong output...
# 12
# 34
您能为我提供一些提示,我如何说服GNU平行假设存在变量内部功能而不是括号。
我认为您所缺少的是bash
将在之前进行替换$(foo {} )
它将参数传递给parallel
。如果用parallel
替换CC_4,则可以看到此信息:
printf "%sn" echo $(foo {} ) ::: "${values[@]}"
echo
{
}
:::
12
34
这意味着您的命令等效于此:
parallel echo { } ::: 12 34
因此,它为什么要打印{ } 12
和{ } 34
。parallel
这里没有{}
替换,因为foo
已将其分为两个单独的ARGS {
和}
。因此,就像xargs
没有{}
时一样,parallel
仅在args上钉在命令的末尾,产生命令:
echo { } 12
echo { } 34
要延迟流程替代,您需要单个引号包装:
parallel echo '$(foo {} )' ::: "${values[@]}"
但是,这导致了另一个问题,因为parallel
产生的过程无法识别功能foo
。但是您可以用export -f
解决:
export -f foo
parallel echo '$(foo {} )' ::: "${values[@]}"
1 2
3 4
同样适用于您的bar
示例。
编辑:您的bar
示例仍然与以前相同,但出于不同的原因。您正在尝试使用array
到CC_23的read
,使用IFS=', '
,但是您的输入不包含任何逗号(或空格),因此您每次都会收到一个元素的数组,并且array[1]
扩展到无。p>但是,如果您这样做,它可以起作用(或者至少是i think 确实可以 - 我不确定您对此示例的预期输出是什么):
values=( "1,2" "3,4" )
parallel echo '$(bar {} )' ::: "${values[@]}"
1 2
3 4