if condition
then
语句1
语句2
...
fi
# example
a=3
b=4
if [ "$a" -lt "$b" ] && [ "$a" -gt 2 ]
then
echo ${a}在范围内
fi
if [ "ok" = "ok" ]
then
echo "equal"
fi
if [ 23 -gt 22 ]
then
echo "dayu"
fi
if [ -e /root/shell/aaa.txt ]
then
echo "existing"
fi
单层if-else
if condition
then
语句1
语句2
...
else
语句1
语句2
...
fi
# example
a=3
b=4
if ! [ "$a" -lt "$b" ]
then
echo ${a}不小于${b}
else
echo ${a}小于${b}
fi
if [ $1 -ge 60 ]
then
echo "xxx"
else [ $1 -lt 60 ]
echo "yyy"
fi
多层if-elif-elif-else
if condition
then
语句1
语句2
...
elif condition
then
语句1
语句2
...
elif condition
then
语句1
语句2
else
语句1
语句2
...
fi
# example
a=4
if [ $a -eq 1 ]
then
echo ${a}等于1
elif [ $a -eq 2 ]
then
echo ${a}等于2
elif [ $a -eq 3 ]
then
echo ${a}等于3
else
echo 其他
fi
if [ $1 -ge 60 ]
then
echo "xxx"
elif [ $1 -lt 60 ]
then
echo "yyy"
else
echo "zzz"
fi
case…esac形式
case $变量名称 in
值1)
语句1
语句2
...
;; # 类似于C/C++中的break
值2)
语句1
语句2
...
;;
*) # 类似于C/C++中的default
语句1
语句2
...
;;
esac
# example
a=4
case $a in
1)
echo ${a}等于1
;;
2)
echo ${a}等于2
;;
3)
echo ${a}等于3
;;
*)
echo 其他
;;
esac
case "$1" in
"a")
echo "a"
;;
"b")
echo "b"
;;
*)
echo "other"
;;
esac
15 循环语句
for…in…do…done
for var in val1 val2 val3
do
语句1
语句2
...
done
# example
for i in a 2 cc
do
echo $i
done
for file in `ls`
do
echo $file
done
for i in $(seq 1 10)
do
echo $i
done
for i in {a..z}
do
echo $i
done
for i in "$*"
do
echo "$i"
done
for j in "$@"
do
echo "$j"
done
# for sc_name in /etc/profile.d/*.sh
for $filename in `ls *.mp3`
do
mv $filename $(basename $filename .mp3).mp4
done
for ((…;…;…)) do…done
for ((expression; condition; expression))
do
语句1
语句2
done
# example
for ((i=1; i<=10; i++))
do
echo $i
done
SUM=0
for((i=1;i<=100;i++))
do
SUM=$[$SUM+$i]
done
echo "sum=$SUM"
while…do…done循环
while condition
do
语句1
语句2
...
done
# example
# 文件结束符为Ctrl+d,输入文件结束符后read指令返回false。
while read name
do
echo $name
done
a=1
while [ $a -lt 10 ]
do
((a++))
echo $a
done
# 构建死循环
while :
do
echo xxxx
done
until…do…done循环(当条件为真时结束)
until condition
do
语句1
语句2
...
done
# 当用户输入yes或者YES时结束,否则一直等待读入
until [ "${word}" == "yes" ] || [ "${word}" == "YES" ]
do
read -p "Please input yes/YES to stop this program: " word
done
break命令(跳出当前一层循环,注意与C/C++不同的是:break不能跳出case语句)
# 该示例每读入非EOF的字符串,会输出一遍1-7
# 该程序可以输入Ctrl+d文件结束符来结束,也可以直接用Ctrl+c杀掉该进程
while read name
do
for ((i=1;i<=10;i++))
do
case $i in
8)
break
;;
*)
echo $i
;;
esac
done
done
continue命令
# 该程序输出1-10中的所有奇数
for ((i=1;i<=10;i++))
do
if [ `expr $i % 2` -eq 0 ]
then
continue
fi
echo $i
done
func() { # 递归计算 $1 + ($1 - 1) + ($1 - 2) + ... + 0
word=""
while [ "${word}" != 'y' ] && [ "${word}" != 'n' ]
do
read -p "要进入func($1)函数吗?请输入y/n:" word
done
if [ "$word" == 'n' ]
then
echo 0
return 0
fi
if [ $1 -le 0 ]
then
echo 0
return 0
fi
sum=$(func $(expr $1 - 1))
echo $(expr $sum + $1)
}
echo $(func 10)
函数内的局部变量
可以在函数内定义局部变量,作用范围仅在当前函数内。
可以在递归函数中定义局部变量
# 命令格式
local 变量名=变量值
# example
#! /bin/bash
func() {
local name=yxc
echo $name
}
func
echo $name
checkpid() {
local i
for i in $*:
do
[ -d "/proc/$i" ] && return 0
done
return 1
}
sed 's/a/aa/' afile
# 替换/,使用别的分隔符
sed 's!/!aa!' afile
# 多命令
sed -e 's/a/aa' -e 's/a/aa' afile
# 简写
sed 's/a/aa;s/a/aa' afile
# 直接修改源文本
sed -i 's/a/aa' afile
# 重定向
sed 's/a/aa' afile > bfile
# 正则
head -5 /etc/passwd | sed 's/...//'
head -5 /etc/passwd | sed 's/s*bin//'
head -5 /etc/passwd | sed 's/s^root//'
# 全局
head -5 /etc/passwd | sed 's/s^root//g'
# 替换第二个
head -5 /etc/passwd | sed 's/s^root//2'
# 扩展正则
sed -r 's/ab+/!/' bfile
sed -r 's/a|b/!/' bfile
sed -r 's/(aa)|(bb)/!/' bfile
# 反向饮用
sed -r 's/(a.*b)/\1:\1/' cfile
# 打印模式空间
head -5 /etc/passwd | sed 's/s^root//p'
# 只输出替换成功行
head -5 /etc/passwd | sed -n 's/s^root//p'
# 输出到文件
head -5 /etc/passwd | sed 's/s^root//w' /tmp/a.txt
# 寻址
head -6 /etc/passwd | sed '1s/s^root/!/'
head -6 /etc/passwd | sed '1,3s/s^root/!/'
head -6 /etc/passwd | sed '1,$s/s^root/!/'
head -6 /etc/passwd | sed '/root/s/bash/!/'
head -6 /etc/passwd | sed '/^bin/s/bash/!/'
head -6 /etc/passwd | sed '/^bin/,$s/bash/!/'
head -6 /etc/passwd | sed '/^bin/,$s/bash/!/g'
# 分组
# 删除d
sed '/ab/d' bfile
# 注意d改变控制流,比如先替换再删除
sed '/ab/d;s/a/!/' bfile
# 追加a,上一行加
sed '/ab/a hello' bfile
# 插入i,下一行加
sed '/ab/i hello' bfile
# 更改c
sed '/ab/c hello' bfile
# 读文件和写文件
sed '/ab/r afile' bfile > cfile
# n下一行
# =打印行号
# q退出
sed 10q afile
sed -n 1,10p afile
多行模式N、D、P
sed 'N;s/hel.lo/!/' afile
保持空间
h和H将模式空间内容存放到保持空间
g和G将保持空间内容取出到模式空间
x交换模式空间和保持空间内容
# practise
# 数据准备
touch sed.txt
vim sed.txt
dong shen
guan zhen d
wo wo
lai lai
le le
# 将“mei nv”这个单词插入到sed.txt第二行后
sed '2a mei nv' sed.txt
# 删除sed.txt文件所有包含wo的行
sed '/wo/d' sed.txt
# 将sed.txt文件中wo替换为ni
sed 's/wo/ni/g' sed.txt
# 将sed.txt文件中的第二行删除并将wo替换为ni
sed -e '2d' -e 's/wo/ni/g' sed.txt