概述
在Linux下经常会遇到需要使用脚本来自动修改配置文件内容的需求,针对这种情况,特别整理了这样几种可以使用的方式方法。(以下几种方式由简入难)
1、清空目标文件并将新内容写入文件并保存。
2、向目标文件中追加新的内容并保存。
3、传参指定修改内容将目标文件中指定内容进行修改并保存。
4、将传递参数修改为一个配置文件,每次执行时默认读取配置文件根据区中的内容修改对应的文件信息。
5、添加条件判断,满足条件时执行4的操作。
注:下面开始实现上述要求的方式方法,约定以下几个文件和文件名:/cfg/target.t(目标文件,/cfg为路径)、/cmd/cmd.sh(执行的shell脚本,/cmd为路径)、cmd.cfg(执行shell脚本相应的配置文件)
文件目录参考:
.
└── cfg_demo
├── cfg(修改目标目录)
│ ├── bak_target.t(备份的目标文件)
│ └── target.t(目标文件)
└── cmd(shell脚本目录)
├── cmd.cfg(shell脚本对应的配置文件)
└── cmd.sh(shell脚本)
3 directories, 4 files
清空目标文件并将新内容写入文件并保存。
:> ${target_file} ;
cat ${cmd_cfg} > ${target_file}
auto eno1
iface eno1 inet dhcp
pre-up ifconfig eno1:0 192.168.0.139
up ifconfig eno1:0 192.168.0.139
auto lo
iface lo inet loopback
执行如下shell命令情况目标文件并将设置好的内容填充进空文件中并保存。
#!/bin/bash
target_file= .. /cfg/target.t
echo "start clear target file message!"
:> ${target_file} ;
echo "clear end."
echo "start input message to target file."
echo "auto eno1" >> ${target_file} ;
echo "iface eno1 inet dhcp" >> ${target_file} ;
echo "pre-up ifconfig eno1:0 192.168.0.111" >> ${target_file} ;
echo "up ifconfig eno1:0 192.168.0.111" >> ${target_file} ;
echo "new file message input end."
echo "please look over target file"
从上面打印信息及最后查看的结果能看出是可以这么做的,但是有点蠢啊。
而且内容是写死的。顺便实现了将cmd.cfg的内容放到目标文件中的功能。脚本内容如下:
使用cat命令将配置文件内容取出重定向到目标文件中
#!/bin/bash
target_file= .. /cfg/target.t
cmd_cfg= ./cmd.cfg
echo "start clear target file message!"
:> ${target_file} ;
echo "clear end."
echo "start input message to target file."
cat ${cmd_cfg} > ${target_file}
echo "please look over target file"
向目标文件中追加新的内容并保存。
追加内容只需要使用>>追加重定向即可。
shell脚本内容如下:
#!/bin/bash
target_file= .. /cfg/target.t
cmd_cfg= ./cmd.cfg
echo "start append message to target file."
cat ${cmd_cfg} >> ${target_file}
echo "please look over target file"
传参指定修改内容将目标文件中指定内容进行修改并保存。
这个需求就有点难度了,首先需要传递K-V参数给脚本,脚本读取K-V参数对到目标文件中将K对应的参数修改为传递的参数V即可。
此外还有一种可能是传递参数为将指定字符串替换为新的字符串。
针对以上两种情况分别进行两种不同的脚本。
传递K-V参数给脚本进行修改目标文件中的指定V值。
sed -i "s/^.*${key} .*$/${key} =${value} /" ${target_file}
while getopts ":k:v:" opt
do
case $opt in
k)
echo "参数key的值$OPTARG "
key= $OPTARG
; ;
v)
echo "参数value的值$OPTARG "
value= $OPTARG
; ;
?)
echo "未知参数"
exit 1; ;
esac
done
echo "参数key的值$key "
echo "参数value的值$value "
serverip= 192.168.0.1
serverport= 8899
addrip= 192.168.0.122
addrport= 6666
#!/bin/bash
target_file= .. /cfg/target.t
cmd_cfg= ./cmd.cfg
echo "start append message to target file."
echo "please look over target file"
while getopts ":k:v:" opt
do
case $opt in
k)
echo "参数key的值$OPTARG "
key= $OPTARG
; ;
v)
echo "参数value的值$OPTARG "
value= $OPTARG
; ;
?)
echo "please input"
echo "./cmd.sh -k key -v value"
exit 1; ;
esac
done
sed -i "s/^.*${key} .*$/${key} =${value} /" ${target_file}
echo "replace success."
传递old-string和new-string将目标文件中old-string内容进行替换。
sed -i "s/$1 /$2 /g" ${target_file}
./cmd.sh old-string new-string
#!/bin/bash
target_file= .. /cfg/target.t
cmd_cfg= ./cmd.cfg
echo "start append message to target file."
sed -i "s/$1 /$2 /g" ${target_file}
echo "please look over target file"
将传递参数修改为一个配置文件,每次执行时默认读取配置文件根据区中的内容修改对应的文件信息。
这里的需求比前一步多了一个读取配置文件中的K-V对的值。只需要循环执行上一步的流程即可。读取K-V对的方式有两种,如下:
第一种方式:
IFS= '='
while read k v
do
echo "$k : $v "
done < ${cmd_cfg}
while read line
do
k= ${line%=*}
v= ${ line
echo "$k : $v "
done < ${cmd_cfg}
#!/bin/bash
target_file= .. /cfg/target.t
cmd_cfg= ./cmd.cfg
IFS= '='
while read k v
do
echo "$k : $v "
done < ${cmd_cfg}
while read line
do
key= ${line%=*}
value= ${ line
echo "$key : $value "
sed -i "s/^.*${key} .*$/${key} =${value} /" ${target_file}
done < ${cmd_cfg}
echo "replace success."
添加条件判断,满足条件时执行5的操作。
#!/bin/bash
target_file= .. /cfg/target.t
cmd_cfg= ./cmd.cfg
if [ -f ${cmd_cfg} ] ; then
echo "cfg file yes."
while read line
do
key= ${line%=*}
value= ${ line
echo "$key : $value "
sed -i "s/^.*${key} .*$/${key} =${value} /" ${target_file}
done < ${cmd_cfg}
echo "replace success."
else
echo "cfg file is no."
fi
补充知识
条件判断
表达式
实例
[ expression ]
[ 1 -eq 1 ]
[[ expression ]]
[[ 1 -eq 1 ]]
test expression
test 1 -eq 1 ,等同于[]
╭─[email protected] ~
╰─➤ [ 1 -eq 1 ] && echo "true" || echo "false"
true
╭─[email protected] ~
╰─➤ [ 1 -eq 2 ] && echo "true" || echo "false"
false
╭─[email protected] ~
╰─➤ [ 1 -eq 2] && echo "true" || echo "false"
zsh: bad pattern: [ 1
整数比较符
比较符
描述
实例
-eq, equal
等于
[ 1 -eq 1 ] 为true
-ne, not equal
不等于
[ 1 -ne 1 ] 为false
-gt, greate than
大于
[ 1 -gt 1 ] 为false
-lt, lesser than
小于
[ 1 -lt 1 ] 为false
-ge, greate or equal
大于或者等于
[ 1 -ge 1 ] 为true
-le, lesser or equal
小于或者等于
[ 1 -le 1 ] 为true
字符串比较符
运算符
描述
实例
==
等于
[ “a” == “a” ] 为true
!=
不等于
[ “a” != “a” ] 为false
-n
字符串长度不等于 0 为真
VAR1=1;VAR2=””,[ -n “
V
A
R
1
”
]
为
t
r
u
e
,
[
−
n
“
VAR1” ]为 true,[ -n “
V A R 1 ” ] 为 t r u e , [ − n “ VAR2” ]为 false
-z
字符串长度等于 0 为真
VAR1=1;VAR2=””,[ -z “
V
A
R
1
”
]
为
f
a
l
s
e
,
[
−
z
“
VAR1” ]为false,[ -z “
V A R 1 ” ] 为 f a l s e , [ − z “ VAR2” ]为 true
注意:使用-n 判断字符串长度时,变量要加双引号,养成好习惯,字符串比较时都加上双引号
文件测试
测试符
描述
实例
-e
文件或者目录存在为真
[ -e path ] path 存在为 true
-f
文件存在为真
[ -f file_path ] 文件存在为 true
-d
目录存在为真
[ -d dir_path ] 目录存在为 true
-r
有读权限为真
[ -r file_path ]file_path有读权限为真
-w
有写权限为真
[ -w file_path ]file_path有写权限为真
-x
有执行权限为真
[ -x file_path ]file_path有执行权限为真
-s
文件存在且不为空为真
[-s file_path]file_path存在且不为空为真
布尔运算符
运算符
描述
实例
!
非关系,条件结果取反
[ ! 1 -eq 2 ]为true
-a
和关系,在[]表达式中使用
[ 1 -eq 1 -a 2 -eq 2 ]为true,两者都为真才为真
-o
或关系,在[]表达式中使用
[ 1 -eq 1 -o 2 -eq 1 ]为true,两者有一真则为真
逻辑判断符
判断符
描述
实例
&&
逻辑和,在[[]]表达式中或判断表达式是否为真时使用
[[ 1 -eq 1 && 2 -eq 2 ]]为 true,[ 1 -eq 1 ] && echo ‘true’,如果&&前面的表达式为true则执行后面的
||
逻辑或,在[[]]表达式中或判断表达式是否为真时使用
[[ 1 -eq 1
整数运算符
运算符
描述
+
加法
–
减法
*
乘法
/
除法
%
取余
运算表达式
实例
$(())
$((1+1))
$[]
$[]
其他运算符
命令
描述
实例
let
赋值并运算
let x++;echo $x 每执行一次 x 加 1,let y–;echo $y 每执行一次 y 减 1,let x+=2 每执行一次 x 加 2,let x-=2 每执行一次 x 减 2
expr
乘法*需要\转义"*"
expr 1 * 2 运算符两边必须有空格,expr( 1 + 2) * 2 使用双括号时要转义,
if语句
if语句用exit结束
单分支
if 条件表达式 ;then
命令
fi
#!/bin/bash
read -p "请输入数字" num
if [ $num -lt 10 ] ; then
echo "${num} 是数字两位数"
fi
.. .
╭─[email protected] ~
╰─➤ bash test.sh
请输入数字3
3是数字一位数
多分支
if 条件表达式 ;then
命令
else
命令
fi
实例:
#!/bin/bash
read -p "请输入数字" num
if [ $num -gt 9 -a $num -lt 100 ] ; then
echo "${num} 是数字两位数"
else
echo "${num} 不是数字两位数"
fi
.. .
╭─[email protected] ~
╰─➤ bash test.sh
请输入数字56
56是数字两位数
╭─[email protected] ~
╰─➤ bash test.sh
请输入数字222
222不是数字两位数
多分支
if 条件表达式 ;then
命令
elif 条件表达式 ;then
命令
else
命令
fi
实例:
#!/bin/bash
num= ` echo $RANDOM`
if [ $num -lt 1000 ] ; then
echo "$num 小于1000"
elif [ $num -ge 1000 -a $num -lt 2000 ] ; then
echo "$num 大于等于1000,小于2000"
elif [ $num -ge 2000 -a $num -lt 3000 ] ; then
echo "$num 大于等于2000,小于3000"
elif [ $num -ge 3000 -a $num -lt 4000 ] ; then
echo "$num 大于等于3000,小于4000"
else
echo "$num 大于等于4000"
fi
.. .
╭─[email protected] ~
╰─➤ bash test.sh
24497大于等于4000
╭─[email protected] ~
╰─➤ bash test.sh
20763大于等于4000
参考链接