我需要在目录中的数千个文件上运行命令。但是,我正在使用的程序需要一个参数文件,在该文件上指示输入和输出的名称。命令如下:
./program parameters_file.txt
这些是我需要在parameter_file.txt上进行编辑的第1-3行。其余各行(未显示)保持不变:
input_file = asd123.OK
input_file2 = asd123.TXT
outfile = asd123.RESULTS_OUT
如图所示,所有文件都具有匹配的名称,并且只有其扩展名更改。
我需要循环执行此操作,以便每次循环重新启动时都会覆盖input_file,input_file2和outfile。诸如此类:用第一个文件名编辑parameters_file.txt,在第一个文件上运行命令,用第二个文件名编辑parameter_file.txt,在第二个文件上运行命令,等等。
关于:
for f in *.OK;
do
input_file = $f
input_file2 = $f.TXT
outfile = $f.RESULTS_OUT
但是我不知道如何将其合并到命令中,并且我无法在parameters_file.txt中编写循环,因为它会使程序崩溃。也许是回显parameters_file.txt还是用sed覆盖?
谢谢。
答案 0 :(得分:2)
执行一个创建输入参数文件的循环,然后运行程序:
for f in *.OK;
do
echo "input_file = $f" > parameters
"input_file2 = $f.TXT" >> parameters
"outfile = $f.RESULTS_OUT" >> parameters
# Add/copy/incorporate the rest of the parameters as you wish
./program parameters
done
答案 1 :(得分:2)
我想这样的事情会实现您想要的:
#!/bin/bash
for file in *.OK; do
sed -i \
-e "s/input_file =.*/input_file = ${file}/" \
-e "s/input_file2.*/input_file2 = ${file%.OK}.TXT/" \
-e "s/outfile.*/outfile = ${file%.OK}.RESULTS_OUT/" \
parameters_file.txt
./program parameters_file.txt
done
答案 2 :(得分:2)
在进程替换中使用printf,不必为替换parameters_file.txt
中的字符串而烦恼。
for f in *.OK; do
prog <(
printf 'input_file = %s\ninput_file2 = %s\noutfile = %s\n' "${f%OK}"{OK,TXT,RESULTS_OUT}
tail -n +4 parameters_file.txt
)
done
答案 3 :(得分:2)
如果要处理数千个文件,每个文件要花费一个小时,则可以考虑使用 GNU Parallel 并行完成4、8或16个操作,并使所有CPU内核忙于处理您付给英特尔如此丰厚的报酬...否则您将在那里待上数周。另外,如果您的网络中有多台计算机, GNU Parallel 也可以在它们之间分配作业和数据,以加快处理速度。
因此,假设您需要处理的所有文件都以*.OK
结尾,那么一个基本的例子是:
parallel -k echo {#} {.} ::: ads123.OK qwe987.OK tyu456.OK
这将输出:
1 ads123
2 qwe987
3 tyu456
所以希望您能看到{#}
只是顺序增加的作业号,{.}
是除去扩展名的文件名。
好吧,现在您要在开始作业之前先处理参数文件,因此最好为要进行预处理的每个作业编写一个bash
函数,如下所示。我将调用函数doit()
:
doit(){
jobnum=$1
name=$2
paramfile="parameters.$jobnum"
echo Processing file: $name with parameters in file: $paramfile
}
# Make our function known to jobs started by GNU Parallel
export -f doit
# Now run the jobs
parallel -k doit {#} {.} ::: *.OK
现在我们要做的就是更改doit()
以准备您的参数,因此我们可以执行以下操作:
doit(){
jobnum=$1
name=$2
paramfile="parameters.$jobnum"
echo Processing file: $name with parameters in file: $paramfile
# Following code supplied by @poshi
echo "input_file = $name" > "$paramfile
echo "input_file2 = $name.TXT" >> "$paramfile"
echo "outfile = $name.RESULTS_OUT" >> "$paramfile"
# Add/copy/incorporate the rest of the parameters as you wish
echo program "$paramfile"
}