![带有命名参数的 GNU Parallel](https://linux22.com/image/208838/%E5%B8%A6%E6%9C%89%E5%91%BD%E5%90%8D%E5%8F%82%E6%95%B0%E7%9A%84%20GNU%20Parallel.png)
我的 Makefile 中有以下命令
parallel \
--eta \
--bar \
--joblog mnist/embedder.joblog \
pipenv run python3 \
-m mnist.train_embedder \
--embedder_name {1} \
--embedder_dim {2} \
--embedder_lr {3} \
--embedder_epochs {4} \
:::: grid/embedder_name \
:::: grid/embedder_dim \
:::: grid/embedder_lr \
:::: grid/embedder_epochs
每个文件包含类似的内容
$ cat grid/embedder_name
ae
cnn
$ cat grid/embedder_dim
24
32
48
64
空运行的结果是
$ parallel \
--dry-run \
--eta \
--joblog mnist/embedder.joblog \
pipenv run python3 \
-m mnist.train_embedder \
--embedder_name {1} \
--embedder_dim {2} \
--embedder_lr {3} \
--embedder_epochs {4} \
:::: grid/embedder_name \
:::: grid/embedder_dim \
:::: grid/embedder_lr \
:::: grid/embedder_epochs
Computers / CPU cores / Max jobs to run
1:local / 96 / 8
Computer:jobs running/jobs completed/%of started jobs/Average seconds to complete
ETA: 0s Left: 8 AVG: 0.00s local:8/0/100%/0.0s pipenv run python3 -m mnist.train_embedder --embedder_name ae --embedder_dim 24 --embedder_lr 0.001 --embedder_epochs 32
ETA: 0s Left: 7 AVG: 0.00s local:7/1/100%/0.0s pipenv run python3 -m mnist.train_embedder --embedder_name ae --embedder_dim 32 --embedder_lr 0.001 --embedder_epochs 32
ETA: 0s Left: 6 AVG: 0.00s local:6/2/100%/0.0s pipenv run python3 -m mnist.train_embedder --embedder_name ae --embedder_dim 48 --embedder_lr 0.001 --embedder_epochs 32
ETA: 0s Left: 5 AVG: 0.00s local:5/3/100%/0.0s pipenv run python3 -m mnist.train_embedder --embedder_name ae --embedder_dim 64 --embedder_lr 0.001 --embedder_epochs 32
ETA: 0s Left: 4 AVG: 0.00s local:4/4/100%/0.0s pipenv run python3 -m mnist.train_embedder --embedder_name cnn --embedder_dim 24 --embedder_lr 0.001 --embedder_epochs 32
ETA: 0s Left: 3 AVG: 0.00s local:3/5/100%/0.0s pipenv run python3 -m mnist.train_embedder --embedder_name cnn --embedder_dim 32 --embedder_lr 0.001 --embedder_epochs 32
ETA: 0s Left: 2 AVG: 0.00s local:2/6/100%/0.0s pipenv run python3 -m mnist.train_embedder --embedder_name cnn --embedder_dim 48 --embedder_lr 0.001 --embedder_epochs 32
ETA: 0s Left: 1 AVG: 0.00s local:1/7/100%/0.0s pipenv run python3 -m mnist.train_embedder --embedder_name cnn --embedder_dim 64 --embedder_lr 0.001 --embedder_epochs 32
ETA: 0s Left: 0 AVG: 0.00s local:0/8/100%/0.0s
--embedder_name
参数列表仍在增长,如果我想在和之间添加参数--embedder_dim
,我必须编辑--embedder_dim {2}
to --embedder_dim {3}
、--embedder_lr {3}
to --embedder_lr {4}
,依此类推。这是乏味且容易出错的。
我可以将位置参数变成命名参数吗?我想象如下
parallel \
--eta \
--bar \
--joblog mnist/embedder.joblog \
pipenv run python3 \
-m mnist.train_embedder \
--embedder_name {embedder_name} \
--embedder_dim {embedder_dim} \
--embedder_lr {embedder_lr} \
--embedder_epochs {embedder_epochs} \
:::: grid/embedder_name \
:::: grid/embedder_dim \
:::: grid/embedder_lr \
:::: grid/embedder_epochs
虽然这会产生大量重复的名称(该字符串embedder_name
在命令中出现三次!),但至少它对于意外错误的参数顺序更加稳健。
如果它是相关的
$ uname -a
Linux t1v-n-5d019513-w-0 5.13.0-1023-gcp #28~20.04.1-Ubuntu SMP Wed Mar 30 03:51:07 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
答案1
--header :
做几乎你想要什么。
它是为 CSV 文件制作的,其中第一行是标题。
因此,您需要在“grid/embedder_name”前面加上“name”:
$ cat grid/embedder_name
name
ae
cnn
$ cat grid/embedder_dim
dim
24
32
48
64
另外,您不需要在每个文件之间使用 :::: 。一个就足够了(但如果您发现它更容易阅读,请保留它们):
parallel --header : echo {name} {dim} :::: grid/embedder_dim grid/embedder_name
(@r_31415 显示了一个不起作用的示例,其中名称放在命令行上。如果您使用:::
- 而不是::::
示例: ,则可以执行此操作parallel --header : echo {foo} ::: foo 1 2 3
)
编辑:
从版本 20220822 开始,您可以执行以下操作:
parallel --header 0 echo {grid/embedder_name} {grid/embedder_dim} :::: grid/embedder_dim grid/embedder_name
parallel --header 0 echo {embedder_name} {embedder_dim} :::: embedder_dim embedder_name
为此,文件的第一行不应有标题。
答案2
是否考虑过将其包装在脚本/函数中?例如
#!/bin/bash
genarglist() {
for ((i=1;i<=$#;i++)) ; do
echo -n " --embedder_${!i} {$i}"
done
for ((i=1;i<=$#;i++)) ; do
echo -n " :::: grid/embedder_${!i}"
done
}
parallel --eta --bar --joblog mnist/embedder.joblog \
pipenv run python3 -m mnist.train_embedder \
$(genarglist $*)
然后只需提供name
, dim
... 作为参数。