Linux-用shell脚本来批量进行文件夹的创建,文件的复制、修改等操作,以及提交任务
之前的博文我记录了如何用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
如第三行所示。