如何在 GNU parallel 中使用 shell 变量?

How to use shell variables with 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 变量不是 defined/printed?

编辑 20151218: 现在我得到了正确的引用,我想介绍一个从另一个函数读取变量的函数,并读取 [=19=].

这是一个没有 GNU parallel 的工作示例(我在发布前 grep 不区分大小写,以便在没有 ./capitalize.sh 的情况下进行测试)。

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

get_key() {
   key=`grep -i $color [=14=] | 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

这应该有效:

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

您正受到引用不充分的困扰。使用函数可能更容易:

doit() {
   color=`echo  | sed 's/e/eee/g' | ./capitalize.sh`
   echo ""
   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可以引入一个shorthand:

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) 大于进程中的可用进程数 table - 即使 capitalize.sh 需要整整一分钟到 运行 (xargs -P0)

我们的想法是使用一个函数来完成所有事情。

#!/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  | cut -d, -f2 | sed 's/e/eee/g' | ./capitalize.sh`
  #extract this element's value from the script's comments.
  key=`grep -i $color  | 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 [=10=] < list.csv