shell脚本 自动改参数

简介

最近发现很多小伙伴该程序参数的时候在手动改,路径复杂的时候费时费力,改完还需要再重新编译运行非常麻烦。
这里介绍一种用shell脚本自动改参数并编译运行的方法。

shell 脚本

脚本:本质是一个文件,文件里面存放的是 特定格式的指令,系统可以使用脚本解析器 翻译或解析 指令 并执行(它不需要编译)
shell 既是应用程序 又是一种脚本语言。

Linux三剑客

Linux 三剑客是(grep,sed,awk)三者的简称,他们通常结合正则一起使用。
grep擅长查找,sed擅长修改文件。awk擅长取列。
给一个链接: Linux三剑客自行了解
这里我直接讲重点 sed -i命令

sed 命令

# 对每行匹配到的第一个字符串进行替换
sed -i 's/原字符串/新字符串/' a.txt 
# 对全局匹配上的所有字符串进行替换
sed -i 's/原字符串/新字符串/g' a.txt 
# 删除所有匹配到字符串的行
sed -i '/匹配字符串/d'  a.txt  
# 特定字符串的行后插入新行
sed -i '/特定字符串/a 新行字符串' a.txt 
# 特定字符串的行前插入新行
sed -i '/特定字符串/i 新行字符串' a.txt
# 把匹配行中的某个字符串替换为目标字符串
sed -i '/匹配字符串/s/源字符串/目标字符串/g' a.txt
# 在文件ab.txt中的末行之后,添加bye
sed -i '$a bye' a.txt   
# 对于文件第3行,把匹配上的所有字符串进行替换
sed -i '3s/原字符串/新字符串/g' a.txt 

介绍具体用法。比如我要改 ./system/controlDict 里的 endtime 参数。
文件内容如下

/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  2.1.1                                 |
|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "system";
    object      controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

application     twoPhaseEulerFoam;




startFrom       startTime;
stopAt          endTime;

startTime  0.0;
endTime    10.01; // 要修改的参数

writeControl    timeStep;
writeInterval   1000;
deltaT     1.0e-3;
purgeWrite      0;

writeFormat     ascii;
//writeFormat     binary;

writePrecision  6;

writeCompression uncompressed;

timeFormat      general;

timePrecision   9;

runTimeModifiable on;

maxCo           1;

maxDeltaT       1e-05;

// ************************************************************************* //

我们可以先用sed命令查看目标行。

# -n p 在终端显示, ^匹配开头 匹配 ./system/controlDict文件中以endTime开头的行
sed -n '/^endTime/p'  ./system/controlDict
#输出结果:
#endTime    10.01;
# 或grep命令可以显示行号
grep -n '^endTime' ./system/controlDict
#输出结果: 
#27:endTime    10.01;

再用sed -i 命令改

#先看看改的对不对
sed -n '27s/.*/endTime    20.01;/p' ./system/controlDict
#输出: endTime    20.01; 
#改对了
#真改了
sed -i '27s/.*/endTime    20.01;/g' ./system/controlDict 
sed -n '/^endTime/p'  ./system/controlDict
#输出结果:
#endTime    20.01;

Shell 传递参数

那有同学又要问了,我这样写代码改不还的是手动改命令里的参数吗?
问得好,介绍一个高级命令

#!/bin/bash
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

为脚本设置可执行权限,并执行脚本,输出结果如下所示:

$ chmod +x test.sh 
$ ./test.sh 1 2 3
Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

相信聪明的同学已经领悟到了。
下面我们写一个同时改writeInterval和endTime两个参数的脚本。

#!/bin/bash
#change_parameters.sh
echo "执行的文件名:$0";
echo "endTime参数改为:$1";
sed -i '27s/.*/endTime    '$1'.01;/g' ./system/controlDict 
sed -n '27,27p' ./system/controlDict 
echo "writeInterval参数改为:$2";
sed -i '30s/.*/writeInterval   '$2';/g' ./system/controlDict 
sed -n '30,30p' ./system/controlDict 

为脚本设置可执行权限,并执行脚本,输出结果如下所示:

$ chmod +x change_parameters.sh 
$ ./change_parameters.sh 20 500
执行的文件名:./change_parameters.sh
endTime参数改为:20
endTime    20.01;
writeInterval参数改为:500
writeInterval   500;

那喜欢思考的同学又要问了,还有没有更牛逼的改法呀?
有,加上正则表达式,awk grep sed 命令基本可以满足任意的修改需求。有需要可以评论区留言。
后续我会推出更高级的教程,结合paraview的python脚本,可以实现cfd程序自动后处理。

重新编译 运行

本质就是把手动操作写在一起。以cfd为例,改完参数后需要重新划分进程,编译,运行。

rm process* -r
blockMesh
./clean.sh
decomposePar
rm *.log *.dat *.xyz
mpirun -np 12 ./Solver  -parallel 2>&1 | tee 1.log
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值