如何在GNU并行中使用shell变量?

时间:2015-12-17 20:55:38

标签: shell variables gnu-parallel

这是list.csv

的内容
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变量?

编辑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

2 个答案:

答案 0 :(得分: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($_) =}'

如果你多次使用$ color,那么--rpl可以引入一个简写:

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

从xargs afficionados我真的希望看到一个使用xargs的解决方案:

  • 保证不混合不同作业的输出 - 即使行长为60k(例如$ color的值为60k长)
  • 将stdout发送到stdout,将stderr发送到stderr
  • 即使作业列表(list.csv)大于进程表中的可用进程数,
  • 也不会跳过作业 - 即使capitalize.sh需要一分钟才能运行(xargs -P0)< / LI>

答案 1 :(得分: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