【问题标题】:Gnu Parallel with multiple arguments - selective command execution具有多个参数的 Gnu Parallel - 选择性命令执行
【发布时间】:2016-04-02 10:11:36
【问题描述】:

我有一个程序需要 3 个参数 -t、-a 和 -s - 例如,

./Run -t 1500 -a 150000 -s filename

此程序会将数据作为一行(7 列)附加到文件“filename”的末尾。

我想研究这两个参数如何影响我的输出范围 t 在(1500,150000 [5000 步数])和 a 在(500,600000 [500 步数])。到目前为止,我正在做的是,

parallel -j+0 ./Run -t {2} -a {1} :::: <(seq 500 500 600000) :::: <seq(1500 5000 15000)

可以看出,对于参数 a 的每个值,参数 t 都会扫描其范围。这会将所有数据打印到文件中,好吧。

但是为了便于使用数据,我希望它在每个参数 a 被完全评估后向文件添加 2 个空白行,以便我可以继续我的处理。这意味着我应该添加

echo "" >> filename

每次更新参数a。

我如何使用 gnu 并行执行此操作?

【问题讨论】:

  • "这个程序会将数据作为一行(7 列)附加到文件 "filename" 的末尾。"如果两个程序同时追加会发生什么?

标签: linux file parallel-processing gnu


【解决方案1】:

我发现并行附加到同一个文件很可怕:在某些情况下这样做是安全的,但在很多情况下并不安全:

# Generate files with a single very long line
parallel -j0 perl -e '\$a=\"1{}\"x10000000\;print\ \$a,\"\\n\"' '>' {} ::: {a..z}
rm -f out.par 
# Grep for the single line in parallel - append to same file
parallel -j0 'grep 1 >> out.par' ::: {a..z}
# This ought to only give a single line for each letter
# But because of race condition some lines are split into two
parallel --tag 'grep {} out.par | wc -l' ::: {a..z}
rm out.par
# Do the same in serial (no race condition)
parallel -j1 'grep 1 >> out.par' ::: {a..z}
# Only a single line per letter
parallel --tag 'grep {} out.par | wc -l' ::: {a..z}
# Do the same in parallel but with serialized output (no race condition)
parallel -j0 grep 1 ::: {a..z} > out.par
# Only a single line per letter
parallel --tag 'grep {} out.par | wc -l' ::: {a..z}

所以如果我是你,我会先将./Run 更改为输出到标准输出(标准输出),这样你就可以这样做:

./Run -t 1500 -2 500 > filename
# And in parallel:
parallel ./Run -t {2} -2 {1} :::: <(seq 500 500 600000) :::: <(seq 1500 5000 15000) > filename

为了解决您最初的问题,我们需要同意,该顺序确实很重要:如果作业以完全随机的顺序输出是不可接受的。因此我们需要--keep-order (-k)。

parallel -k ./Run -t {2} -2 {1} :::: <(seq 500 500 600000) :::: <(seq 1500 5000 15000) > filename

现在我们只需要做一些只在第一个参数是 11500 时运行的东西:

parallel -k './Run -t {2} -2 {1}; if [ {2} -eq 11500 ]; then echo "";fi' :::: <(seq 500 500 600000) :::: <(seq 1500 5000 15000) > filename

我不确定你需要它来做什么,但你可能想看看--tag,因为这可能对你有用。

【讨论】: