之前的博文我记录了如何用fortran来修改文件,之后在运行的过程中发现用Fortran的代码来修改文件,文件的每行开头都会有一个空格,这个空格会影响到文件的读取。我搜索了很久都没有找到能够去除这个空格的方法。于是尝试用Linux本身来修改文件。发现sed这个命令可以满足我的要求,但是一次只可以修改一个文件,我需要循环执行这个sed命令。想到以前阅读过很多shell脚本,里边有很多循环之类的命令,于是就想到用shell脚本来实现我的想法。

对于文件的复制来说,虽然可以用之前博文中提到的echo等组合命令实现,但是这种方法只复制几个文件的话很有效,对于几十个,上百个乃至更多的文件的操作就不太方便了。用shell脚本来批量执行复制命令就简单得多了,但前提是文件或者文件夹的名字是规律的,可以循环的。

本文就记录一下简单的shell脚本的编写,以及对命令的解释。

批量进行文件夹的创建以及文件的复制:

 1 #! /bin/bash
 2 
 3 for i in $(seq 682 702)
 4 do
 5   echo "make directory postproc$i and copy files"
 6   mkdir postproc$i
 7   cd zzz
 8   cp * ../postproc$i
 9   cd ..
10   echo finish copy
11 done
12 
13 for j in $(seq 682 702)
14 do
15   echo copy rstile to postproc$j
16   cp ../SD7003/rstfile.$j postproc$j/
17   echo finish copy
18 done

1行 第一行一定要这样写,告诉系统这个脚本会在bash下运行。同时shell脚本中以#开头作为注释,#之后的内容会跳过不执行。

3行 for循环,shell中变量是直接定义的,比如本行的 i ,但是引用变量时要在变量前加 $,变量名可以用{ }括起来,也可以不括。seq 682 702的意思是会在682与702之前产生连续的整数。

4行 do done,命令集,在这之间的命令会循环执行。

5行 echo输出字符串,可以加双引号,也可以不加,比如15行。

6行  mkdir创建文件夹,名字为 postproc$i,这里 $i 表示引用了变量 i。这条命令执行后会创建一系列文件夹,名字分别为postproc682,postproc683 ···,postproc702。这条命令实现了在Linux中批量创建文件夹。

7行 cd 进入文件夹zzz中。

8行 cp 复制文件,* 表示复制该文件夹下的所有文件。../postproc$i 表示将文件复制到上一级目录中的 postproc$i 文件夹内。这里引用了变量 i,即$i,表示postproc682,postproc683 ···,postproc702这些文件夹。

9行 cd ..表示退出当前文件夹zzz,进入到上一级文件夹中。

11行 done,命令结束。

13~18行,复制另外的一些文件。

批量修改文件:

 1 #! /bin/bash
 2 
 3 for i in $(seq 671 675)
 4 
 5 do
 6 
 7   echo Go into postproc$i
 8 
 9   cd postproc$i 
10    
11   sed  "s/671/$i/" auxparameters.inp  # Modify the number to this time_sequence
12   j=$(echo $i \* 100 |bc)  # There is no blank before and after "="; 100 is number of iterations for restart file
13   sed  "s/58400/$j/" parameters.inp  # Modify the iteration number for start postprocess
14 
15   sbatch bubbleDef.script
16   sleep 30
17 
18   cd ..
19 
20   echo Finish
21 
22 done

11行 sed命令用于修改文件。用法为 sed “s/A/B” file。s表示取代、替换,A表示要被替换的内容,B表示要替换为什么内容,file表示要修改的文件的名字。在sed命令中可以直接引用变量。本行中,将 auxparameters.inp 中的671替换为 $i。

         更多sed的用法,可以参考:

         https://www.runoob.com/linux/linux-comm-sed.html

12行 我要将变量 i 乘以100赋给变量 j,在shell中乘法要在乘号前加 \。变量赋值直接用 =,但是注意 = 前后不能有空格。

         更多shell中的运算,可以参考:

         https://www.runoob.com/linux/linux-shell-basic-operators.html 

         https://www.cnblogs.com/chengmo/archive/2010/09/30/1839556.html

15行 sbatch 表示提交 bubbleDef.script这个命令。超算中需要用sbatch这个命令提交作业。

16行 sleep 30,字面意思,就是暂停执行30秒,30秒之后再接着执行下面的命令。因为总担心上一个提交命令用时会稍微长一点,我在这里将命令暂停30秒,让上一个命令有足够的时间完成。30秒,按照我的经验来看是足够的。而且我不确定要不要暂停30秒再接着执行,但是加上去不会有错。

18行 不要忘记退出当前文件夹。

shell脚本的执行

shell脚本文件通常会有后缀或者扩展名 .sh,但是后缀不会影响脚本的执行。

一种执行方法:(把name换成需要执行的脚本名字即可)

chmod +x ./name.sh #赋给shell脚本可执行权限,然后
./name.sh #执行

另一种,直接运行:

bash name.sh

shell脚本中调用其他的shell脚本

在shell脚本中写入:

bash name.sh

就可以直接调用其他的shell脚本。比如我想先创建文件夹及复制文件,然后再修改文件,可以调用:

 1 #! /bin/bash
 2 
 3 bash z_copy_file.sh
 4 
 5 for i in $(seq 707 721)
 6 
 7 do
 8 
 9   echo Go into postproc$i
10 
11   cd postproc$i
12 
13   sed -i "s/585/$i/" auxparameters.inp  # Modify the number to this time_sequence
14   j=$(echo $i \* 100 |bc)  # There is no blank before and after "="; 100 is number of iterations for restart file
15   sed -i "s/58500/$j/" parameters.inp  # Modify the iteration number for start postprocess
16 
17   sbatch bubbleDef.script
18   sleep 60
19 
20   cd ..
21 
22   echo Finish
23 
24 done

如第三行所示。

版权声明:本文为cfdchen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/cfdchen/p/13417555.html