如何进行循环以获取输入和输出

时间:2018-09-20 16:11:17

标签: bash

我有这样的命令行:

myscript constant/tap.txt -n base.dat -c normal/sta0.grs -o normal/brs0.opm 

我有100个.grs文件,我需要生成100个.opm文件。

我想将上面的命令放入执行以下操作的循环中:

myscript constant/tap.txt -n base.dat -c normal/sta0.grs -o normal/brs0.opm 
myscript constant/tap.txt -n base.dat -c normal/sta1.grs -o normal/brs1.opm 
myscript constant/tap.txt -n base.dat -c normal/sta2.grs -o normal/brs2.opm 
myscript constant/tap.txt -n base.dat -c normal/sta3.grs -o normal/brs3.opm 
myscript constant/tap.txt -n base.dat -c normal/sta4.grs -o normal/brs4.opm 

.
.
.
myscript constant/tap.txt -n base.dat -c normal/sta100.grs -o normal/brs100.opm 

我试图像下面这样:

#!/bin/bash
# Basic until loop
counter=100
until [ $counter -gt 100 ]
do
myscript constant/tap.txt -n base.dat -c normal/sta100.grs -o normal/brs100.opm

done
echo All done

但是我找不到在循环中设置参数更改的方法

在上面的命令中,这些对于每次运行都是恒定的:

myscript constant/tap.txt -n base.dat -c

每个循环中唯一更改的是以下输入和输出:

normal/sta100.grs 
normal/brs100.opm

我在sta.grs文件夹中有100个normal,并且我想在brs.opm文件夹中创建100个normal

3 个答案:

答案 0 :(得分:0)

#!/bin/bash
counter=0
until ((counter>100))
do
    myscript constant/tap.txt -n base.dat -c normal/sta$counter.grs -o normal/brs$counter.opm
    ((++counter))
done

echo 'All done'

答案 1 :(得分:0)

这是GNU parallel的绝佳用例:

find normal -name '*.grs' |
parallel myscript constant/tap.txt -n base.dat -c {} -o {.}.opm

编写的代码越少,所犯的错误也就越少。这很好地概括了以更复杂的模式命名文件的情况。而且您可以免费获得并行化(可以使用-j1摆脱并行化)。

答案 2 :(得分:0)

您可以使用如下所示的for循环来代替手动递增计数器:

for i in {0..100}; do
    myscript constant/tap.txt -n base.dat -c normal/sta"$i".grs -o normal/"$i".opm
done

此外,请注意,这将以一种不直观的方式进行排序:

1.opm
10.opm
100.opm
11.opm
12.opm

因此可能在所有for i in {000..100}; do中使用带填充数字。这需要Bash 4.0或更高版本;如果没有,您可以做类似的事情

for i in {0..100}; do
    printf -v ipad '%03d' "$i"
    myscript constant/tap.txt -n base.dat -c normal/sta"$ipad".grs \
        -o normal/"$ipad".opm
done

其中printf行将计数器的填充版本放入ipad变量中。

(如果您的Bash早于3.1,则不能使用printf -v而必须这样做

ipad=$(printf '%03d' "$i")

相反。)