之前的博文我記錄了如何用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
如第三行所示。