как исправить неправильное извлечение параллельной подстроки GNU - PullRequest
1 голос
/ 15 марта 2019

Я пытался использовать извлечение подстроки в bash-скрипте, смешанном с 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 параллельно предполагать, что переменная внутри функции существует и не является скобками.

1 Ответ

2 голосов
/ 15 марта 2019

Я думаю, что вам не хватает того, что bash выполнит подстановку процесса $(foo {} ) до того, как передаст аргументы parallel.Это можно увидеть, если заменить parallel на printf "%s\n":

printf "%s\n" echo $(foo {} ) ::: "${values[@]}"
echo
{
}
:::
12
34

. Это означает, что ваша команда эквивалентна следующему:

parallel echo { } ::: 12 34

И, следовательно, почему она печатает { } 12и { } 34.Здесь нет {} для замены parallel, поскольку foo разделил его на два отдельных аргумента, { и }.Так же, как xargs делает, когда нет {}, parallel просто привязывает аргументы к концу команды, давая команды:

echo { } 12
echo { } 34

Чтобы отложить подстановку процесса, вам нужночтобы заключить его в одинарные кавычки:

parallel echo '$(foo {} )' ::: "${values[@]}"

Однако это приводит к другой проблеме, поскольку процесс, порожденный parallel, не распознает функцию foo.Но вы можете решить это с помощью export -f:

export -f foo
parallel echo '$(foo {} )' ::: "${values[@]}"
1 2
3 4

Аналогично для вашего bar примера.

Edit : ваш пример bar все еще печатает то же самоекак это было раньше, но по другой причине.Вы пытаетесь read первый аргумент bar в array с IFS=', ', но ваш ввод не содержит запятых (или пробелов), поэтому вы каждый раз получаете массив из одного элемента,и array[1] расширяется до нуля.

Но если вы сделаете это вместо этого, это сработает (или, по крайней мере, я думаю, это сработает - я не уверен, каков ваш ожидаемый результат для этогопример):

values=( "1,2" "3,4" )
parallel echo '$(bar {} )' ::: "${values[@]}"
1 2
3 4
...