2015-12-17 5 views
1

Это содержание list.csv:Как использовать переменные оболочки с параллельным GNU?

Apple,Red,10 
Banana,Yellow,3 
Coconut,White,18 

Предположим, у меня есть эта GNU parallel команду:

parallel -a list.csv -j0 -C, \ 
color=`echo {2} | sed 's/e/eee/g' | ./capitalize.sh` ";" \ 
echo "{2}" ";" \ 
echo "$color" ";" 

Чтобы получить:

Red 
REEED 
Yellow 
YEEELLOW 
White 
WHITEEE 

Почему не color переменная определяется/печататься?

EDIT 20151218: Теперь, когда я получил квотирование право, я хотел бы представить функцию чтения переменной из другой функции, и чтение $0.

Это рабочий пример без GNU parallel (я сделал grep без учета регистра перед отправкой, чтобы облегчить тестирование без ./capitalize.sh).

while read line; do 
doit() { 
    color=`echo $1 | cut -d, -f2 | sed 's/e/eee/g' | ./capitalize.sh` 
} 
export -f doit 

get_key() { 
    key=`grep -i $color $0 | cut -d, -f2` 
} 
export -f get_key 
        #note that I would use parallel's `-C,` here instead of `cut`. 
    doit $line  #get CSV's 2nd element and make it look like the one in script. 
    get_key   #extract this element's value from the script's comments. 
    echo "color: $color" 
    echo "key: $key" 
done < list.csv 

#Key database in the shell script 
# REEED,r-key 
# YEEELLOW,y-key 
# WHITEEE,w-key 

Работа выход:

color: REEED 
key: r-key 
color: YEEELLOW 
key: y-key 
color: WHITEEE 
key: w-key 
+0

Это настолько неправильно, что я не уверен, что начиная с существующего кода разумно. Вы можете подумать о резервном копировании и описании того, что вы на самом деле пытаетесь выполнить. –

+0

(и почему параллель является частью этой цели - в целом, если вы хотите, чтобы результат был в определенном порядке, параллель не является обычно подходящим инструментом для работы, поскольку нет никакой гарантии, что одна задача, которую она порождает, t начать печать в середине вывода другого, чтобы избежать необходимости использования '-k' /' -keep-order' для буферизации и сборки вывода). –

+0

... во всяком случае, если вы используете только параллель, потому что его поддержка ввода CSV, есть далеко, ** далеко ** лучшие способы сделать это в оболочке без нее. (И все остальное - вы можете выполнять строковые манипуляции и капитализацию, используя только встроенные оболочки, гораздо эффективнее, чем запуск внешних инструментов, таких как 'sed'). –

ответ

1

Идея состоит в том, чтобы использовать одну функцию для выполнения всего.

#!/bin/bash 

#Key database in the shell script 
# REEED,r-key 
# YEEELLOW,y-key 
# WHITEEE,w-key 

doit() { 
    # get CSV's 2nd element and make it look like the one in script. 
    color=`echo $3 | cut -d, -f2 | sed 's/e/eee/g' | ./capitalize.sh` 
    #extract this element's value from the script's comments. 
    key=`grep -i $color $1 | cut -d, -f2` 
    echo "color: $color" 
    echo "key: $key" 
} 
export -f doit 

#note that I would use parallel's `-C,` here instead of `cut`. 
parallel -C, doit $0 < list.csv 
2

Это должно работать:

parallel -a list.csv -j0 -C, 'color=`echo {2} | sed "s/e/eee/g" | ./capitalize.sh`' ";" echo "{2}" ";" echo '"$color"' ";" 

Вы удара неадекватным процитировать. Это может быть проще использовать функцию:

doit() { 
    color=`echo $2 | sed 's/e/eee/g' | ./capitalize.sh` 
    echo "$2" 
    echo "$color" 
} 
export -f doit 
parallel -a list.csv -j0 -C, doit 

Если это реальная цель, которую вы можете использовать {=}, вместо которой делается для подобных ситуаций:

parallel -a list.csv -j0 -C, echo {2}";" echo '{=2 s/e/eee/g; $_=uc($_) =}' 

Если вы используете $ цвет несколько раз, то --rpl может ввести сокращенный:

parallel --rpl '{clr} s/e/eee/g; $_=uc($_)' -a list.csv -j0 -C, echo {2}";" echo '{2clr} and again: {2clr}' 

От xargs я Любители творчества действительно хотел бы видеть решение с использованием xargs, что:

  • гарантирует не смешивание выходных данных с разных заданий - даже если линии имеют длину 60k (например, значение $ color равно 60k)
  • отправляет stdout на stdout, а stderr на stderr
  • не пропускает задания, даже если список заданий (list.csv) больше, чем количество доступных процессов в процессе таблица - даже если capitalize.sh занимает полную минуту для запуска (xargs -P0)
+0

Ваше первое предложение работает отлично. Мне не повезло с этой функцией, потому что я не хочу, чтобы он сразу распечатывал результат: он будет напечатан и указан позже в коде. Поскольку мы идем глубже по кроличьей дыре, у меня теперь есть проблема с чтением этой переменной из другой переменной. См. Обновленный вопрос. – octosquidopus

+0

@octosquidopus Легче увидеть решение, если вы покажете нам рабочий код перед его переносом в GNU Parallel. –

+0

Я обновил свой вопрос на примере, и я переписываю команду 'GNU parallel' для использования функций, потому что мои вложенные кавычки теперь близки к неуправляемым). – octosquidopus

 Смежные вопросы

  • Нет связанных вопросов^_^