3

我需要通过将目录中的一组文件传递给 matlab 或 python 脚本来处理它们。

对于目录中的每个输入文件 FileName.IN,我需要获取一个输出文件 FileName.OUT。

解决方案是 Python 还是 bash 脚本并不重要。

为了实现我的目标,我尝试了 GNU Make(或 Python Snakemake),但是我有点坚持。看起来我可以说 GNU Make 来做: “嘿,对于每个输出(目标)文件 FileName.out 搜索相应的 FileName.IN(先决条件)”

但是,如前所述,我想做的恰恰相反。

  • make(或)是snakemake正确的选择吗?
  • 你还有什么建议?

我的makefile代码看起来像这样,但它不起作用(我是 GNU make 的新手):

in_files = *.IN
out_files = *.out
$(out_files) : $(in_files)
    matlab -nosplash -nodesktop -r "a_matlab_function('$<','$@')"
4

2 回答 2

5

我对 Snakemake 一无所知,但在 GNU Make 中,您可以转换in_filesout_files

in_files = $(wildcard *.IN)
out_files = $(in_files:.IN=.out)

然后你制作一个取决于所有输出的虚拟目标:

all: $(out_files)
.PHONY: all

最后是从一个输入创建一个输出的规则:

%.out: %.IN
    matlab -nosplash -nodesktop -r "a_matlab_function('$<','$@')"
于 2017-01-17T14:15:07.513 回答
2

我想你只想要一个bashfor 循环:

for f in *.IN; do
   out=${f%IN}OUT                # Work out name of output file
   echo IN:"$f"                  # Show input file to user
   echo OUT:"$out"               # Show output file to user
   matlab <options> "$f" "$out"  # Run Matlab
done

所以,如果我有这些文件:

ls *IN

aThird.IN   
another one.IN
b.IN

我会得到这个:

IN:aThird.IN
OUT:aThird.OUT
IN:another one.IN
OUT:another one.OUT
IN:b.IN
OUT:b.OUT

或者,作为单行:

for f in *.IN; do out=${f%IN}OUT; matlab ... "$f" ... "$out"; done

备注

尽管您的问题建议使用make,但没​​有明确的迹象表明您是否总是希望运行所有作业,或者有时某些作业是否不需要运行 - 大概是因为输出文件已经存在并且没有必要运行它们。如果您不希望每次都运行所有作业,那么使用make可能会更好。

此外,如果 Matlab 可以运行并行实例,那么GNU Parallel语法非常适合这样的事情:

parallel --dry-run matlab {} {.}.OUT ::: *IN

输出

matlab another\ one.IN another\ one.OUT
matlab aThird.IN aThird.OUT
matlab b.IN b.OUT 

在这里,向--dry-run您展示了将要运行的命令,尽管它目前没有运行任何东西。

于 2017-01-17T14:14:13.743 回答