如何将shell变量与GNU并行使用?
这是如何将shell变量与GNU并行使用?,shell,variables,gnu-parallel,Shell,Variables,Gnu Parallel,这是list.csv的内容: Apple,Red,10 Banana,Yellow,3 Coconut,White,18 假设我有这个gnupallel命令: 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 WHITEE
list.csv
的内容:
Apple,Red,10
Banana,Yellow,3
Coconut,White,18
假设我有这个gnupallel
命令:
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
为什么没有定义/打印颜色变量
编辑20151218:
既然我正确地引用了,我想介绍一个函数,从另一个函数读取变量,然后读取$0
这是一个没有GNU parallel
的工作示例(我在发布之前使grep
不区分大小写,以便于在没有/capitalize.sh
的情况下进行测试)
这应该起作用:
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)
我们的想法是用一个函数来完成所有的事情
#!/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
#/bin/bash
#shell脚本中的密钥数据库
#里德,r键
#YEEELLOW,y键
#怀蒂,w-基
doit(){
#获取CSV的第二个元素,并使其看起来像脚本中的元素。
color=`echo$3 | cut-d,-f2 | sed's/e/eee/g'./capitalize.sh`
#从脚本的注释中提取此元素的值。
key=`grep-i$color$1 | cut-d,-f2`
回声“颜色:$color”
echo“key:$key”
}
出口-f doit
#注意,这里我将使用parallel的“-C”,而不是“cut”。
并行-C,doit$0
这是非常错误的,我不确定从现有代码开始是否合理。你可以考虑备份和描述你实际上想要完成的事情。(为什么并行是该目标的一部分——一般来说,如果您希望输出以一个明确的顺序,并行不是典型的适合该工作的工具,因为不能保证它产生的一个任务不会在另一个输出的中间开始打印,以避免需要使用<代码> -k/代码> /<代码> -KEEP-O。rder
以缓冲和重新组装输出)…无论如何,如果您只使用parallel,因为它支持CSV输入,那么在没有它的shell中,有很多更好的方法来实现这一点。(以及其他一切——你可以只使用shell内置程序来进行字符串操作和大写,比启动外部工具(如sed
)要有效得多。)@CharlesDuffy我可以挑战你写这个:parallel-a list.csv-j0-C,echo{3};“echo'{=2 s/e/eee/g;s/\b(\w)/uc($1)/ge=}'使用xargs-P…?@CharlesDuffy是的,但您需要确保不同作业的输出不会混合(即,如果并行运行100个作业,“echo{3}”,后面必须跟第二个echo,而不是另一个作业的“echo{3}”)。您的第一个建议效果很好。我对该函数的运气不太好,因为我不希望它立即打印结果:它将在以后的代码中打印和引用。随着我们深入兔子洞,我现在在从另一个变量中读取此变量时遇到问题。请参阅更新的问题。@octosquidopus它是e如果您在将其放入GNU Parallel之前向我们展示工作代码,则更容易看到解决方案。我用一个示例更新了我的问题,并且我正在重写我的GNU Parallel
命令以使用函数,因为我的嵌套引号现在几乎无法管理)。
parallel --rpl '{clr} s/e/eee/g; $_=uc($_)' -a list.csv -j0 -C, echo {2}";" echo '{2clr} and again: {2clr}'
#!/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