printf ‘输出类型输出格式’ 输出内容 输出类型 : %ns :输出字符串。n是数字指代输出几个字符 %ni :输出整数。n是数字指代输出几个数字 %m.nf : 输出浮点数。m和n是数字,指代输出的整数位数和小数位数。如%8.2f 代表共输出8位数,其中2位是小数,6位是整数。 输出格式 : \a : 输出警告声音 \b : 输出退格键,也就是Backspace键 \f : 清楚屏幕 \n : 换行
awk ‘条件1{动作1} 条件2{动作2}…’ 文件名 条件(Pattern): 一般使用关系表达式作为条件。这些关系表达式非常多,具体参考表12-3所示,例如 : x > 10 判断变量x是否大于10 x == y 判断变量x是否等于变量y A ~ B 判断字符串A中是否包含能匹配B表达式的子字符串 A !~ B 判断字符串A中是否不包含能匹配B表达式的子字符串 动作(Action): 格式化输出 流程控制语句
sed主要是用来将数据进行选取、替换、删除、新增的命令,我们看看命令的语法 : sed 【选项】‘【动作】’ 文件名 选项 : -n 一般sed命令会 把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕。 -e 允许对输入数据英语多条sed命令编辑。 -f 脚本文件名 :从sed脚本中读入sed操作,和awk命令的-f非常类似, -r 在sed的修改结果直接修改读取数据的文件,而不是由屏幕输出 动作 : a : 追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。 c : 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结。 i : 插入,在当期行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。 d : 删除,删除指定的行。 p :打印,输出指定的行。 s :字串替换,用一个字符串替换另外一个字符串。格式为“行范围 s/ 旧字串/新字串/g“ (和vim中的替换格式类似) 对sed命令要注意,sed所做的修改并不会直接改变文件的内容(如果是用管道符接收的命令的输出,这种情况连文件都没有),而是把修改结果只是显示到屏幕上,除非用“-i”选项才会直接修改文件
排序命令 sort sort 【选项】 文件名 选项 : -f :忽略大小写 -b :忽略每行前面的空白部分 -n :以数值型进行排序,默认使用字符串型排序 -r :反向排序 -u :删除重复行。就是uniq命令 -t :指定分隔符,默认是分隔符是制表符 -k n[m] : 按照指定的字段范围排序。从第n字段开始,m字段结束(默认到行末尾) sort 命令默认是用每行开头第一个字符来进行排序的,比如 : sort -n -t “:” k 3,3 /etc/passwd 当然“-k” 选项可以直接使用 “-k 3”,代表从第三字段到行尾都排序(第一个字符先排序,如果一致,第二个字符再排序,直到行尾) uniq unid命令是用来取消重复行的命令,其实和“sort -u”选项是一样的。命令格式如下 : uniq 【选项】文件名 -i :忽略大小写 统计命令 wc wc 【选项】文件名 选项 : -l :只统计行数 -w :只统计单词数 -m :只统计字符数
测试选项 | 作用 |
---|---|
-b 文件 | 判断该文件是否存在,并且是否为块设备文件(是块设备文件为真) |
-c 文件 | 判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真 |
-d 文件 | 判断该文件是否存在,并且是否为目录文件(是目录为真) |
-e 文件 | 判断该文件是否存在(存在为真) |
-f 文件 | 判断该文件是否存在,并且是否为普通文件(是普通文件为真) |
-L 文件 | 判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真 |
-p 文件 | 判断该文件是否存在,并且是否为管道文件(是管道文件为真) |
-s 文件 | 判断该文件是否存在,并且是否为非空(非空为真) |
-S 文件 | 判断该文件是否存在,并且是否为套接字文件(是套接字文件为真) |
test是非常完善的判断命令,还可以判断文件的权限。
测试选项 | 作用 |
---|---|
-r 文件 | 判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真) |
-w 文件 | 判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真) |
-x 文件 | 判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真) |
-u 文件 | 判断该文件是否存在,并且是否该文件拥有SUID权限(有SUID权限为真) |
-g 文件 | 判断该文件是否存在,并且是否该文件拥有SGID权限(有SGID权限为真) |
-k 文件 | 判断该文件是否存在,并且是否该文件拥有SBit权限(有SBit权限为真) |
测试选项 | 作用 |
---|---|
文件 1 -nt 文件 2 | 判断文件 1 的修改时间是否比文件 2 的新(如果新则为真) |
文件 1 -ot 文件 2 | 判断文件 1 的修改时间是否比文件 2 的旧(如果旧则为真) |
文件 1 -ef 文件 2 | 判断文件 1 是否和文件 2 的Inode号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
测试选项 | 作用 |
---|---|
整数 1 -eq 整数 2 | 判断整数 1 是否和整数 2 相等(相等为真) |
整数 1 -ne 整数 2 | 判断整数 2 是否和整数 2 不相等(不相等位置) |
整数 1 -gt 整数 2 | 判断整数 1 是否大于整数 2 (大于为真) |
整数 1 -lt 整数 2 | 判断整数 1 是否小于整数 2(小于为真) |
整数 1 -ge 整数 2 | 判断整数 1 是否大于等于整数 2(大于等于为真) |
整数 1 -le 整数 2 | 判断整数 1 是否小于等于整数 2(小于等于为真) |
测试选项 | 作用 |
---|---|
-z 字符串 | 判断字符串是否为空(为空返回真) |
-n 字符串 | 判断字符串是否为非空(非空返回真 |
字符串1 == 字串2 | 判断字符串1是否和字符串2相等(相等返回真) |
字串 1 != 字串 2 | 判断字符串1是否和字符串2不相等(不相等返回真) |
测试选项 | 作用 |
---|---|
判断 1 -a 判断 2 | 逻辑与,判断 1 和判断 2 都成立,最终的结果才为真 |
判断 1 -o 判断 2 | 逻辑或,判断 1 和 判断 2 有一个成立,最终的结果就为真 |
!判断 | 逻辑非,使原始的判断式取反 |
1)单分之if条件语句 单分之条件语句最为简单,就是只有一个判断条件,如果符合条件则执行某个程序,否则什么事情都不做。语法如下 : if [ 条件判断式 ] ; then 程序 fi 单分之条件语句需要注意几个点 :
#!/bin/bash
aa=$( jps | grep TestDemo | awk '{print $2}' )
if [ "$aa" != "TestDemo" ]
then
java -cp /root/test-demo-0.0.1-SNAPSHOT.jar com.example.testdemo.TestDemo
else
echo "java is ok"
fi
2)双分支if条件语句 if [ 条件判断式 ] then 条件成立时,执行的程序 else 条件不成立时,执行的另一个程序 fi 案例2 :
#!/bin/bash
aa=$( jps | grep TestDemo | awk '{print $2}' )
if [ "$aa" != "TestDemo" ]
then
java -cp /root/test-demo-0.0.1-SNAPSHOT.jar com.example.testdemo.TestDemo
else
echo "java is ok"
fi
3)多分支if条件语句 if [ 条件判断式 1 ] then 当条件判断式 1 成立时,执行程序1 elif [ 条件判断式 2 ] then 当条件判断式 2 成立时,执行程序 2 else 当所有条件都不成立时,最后执行此程序 fi 案例3 :
#!/bin/bash
read -p "Please input a filename: " filename
if [ -z $filename ]
then
echo "11111"
exit 101
elif [ ! -e $filename ]
then
echo "2222222"
exit 102
elif [ -f $filename ]
then
echo "$filename is putong"
elif [ -d $filename ]
then
echo "$filename is dire"
else
echo "$filename is other file"
fi
案例4 :
#!/bin/bash
#字符界面加减乘除计算器
read -t 30 -p "Please input num1 : " num1
read -t 30 -p "Please input num2 : " num2
#通过 read 命令接收要计算的数值,并赋予变量num1和num2
read -t 30 -p "Please input a operator : " ope
# 通过 read 命令接收要计算的符号,并赋予变量ope
if [ -n "$num1" -a -n "$num2" -a -n "$ope" ]
#第一层判断,用来判断num1、num2和ope中都有值
then
test1=$(echo $num1 | sed ' s/[0-9]//g')
test2=$(echo $num2 | sed 's/[0-9]//g')
#定义变量test1和test2的值为$(命令)的结果
#后续命令作用是,把变量test1的值替换为空。如果能替换为空,证明num1的值为数字
#如果不能替换为空,证明num1的值为非数字。我们使用这种方法判断变量num1的值为数字
#用同样的方法测试test2变量
if [ -z "$test1" -a -z "$test2" ]
# 第二层判断,用来判断num1和num2为数值
#如果变量test1和test2的值为空,则证明num1和num2是数字
then
#如果 test1和test2是数字,则执行以下命令
if [ "$ope" == '+' ]
#第三层判断用来确认运算符
#测试变量$ope中是什么运算符
then
value=$(( $num1 + $num2 ))
#如果是加号则执行加法运算
elif [ "$ope" == '-' ]
then
value=$(( $num1 - $num2 ))
#如果是减号,则执行减法运算
elif [ "$ope" == '*' ]
then
value=$(( $num1 * $num2 ))
elif [ "$ope" == '/' ]
then
value=$(( $num1 / $num2 ))
else
echo "Please enter a valid symbol"
#如果运算符不匹配,提示输入有效的符号
exit 10
# 并退出程序,返回错误代码10
fi
else
# 如果test1和test2不为空,说明num1和num2不是数字
echo "Please enter a valid value"
#则提示输入有效的数值
exit 11
#并退出程序,返回错误代码 11
fi
else
echo "qing shuru neirong"
exit 12
fi
echo "$num1 $ope $num2 : $value"
4)多分支 case 条件语句 case 语句和if … elif … else 语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系。case语句语法如下 : case $变量名 in “值 1” ) 如果变量的值等于值1,则执行程序 1 ;; “值 2” ) 如果变量的值等于值2,则执行程序 2 ;; … 省略其他分支… * ) 如果变量的值都不是以上的值 则执行此程序 ;; esac 这个语句需要注意以下内容 : case 语句,会取出变量中的值,然后与语句体中的值逐一比较。如果数值符合,则执行对应的程序,如果数值不符,则依次比较下一个值。如果所有的值都不符合,则执行“)” (“”代表所有其他值)中的程序 case语句以“case” 开头,以 “esac” 结尾。 案例5 :
#!/bin/bash
echo "want to beijing,please input 1"
echo "want to shanghai,please input 2"
echo "want to chendu,please input 3"
read -t 30 -p "please input your choice: " cho
case $cho in
"1")
echo "beijing111111111"
;;
"2")
echo "shanghai22222222"
;;
"3")
echo "chendu333333333"
;;
*)
echo "error input"
;;
esac
3 for 循环 for 循环是固定循环,也就是在循环时已经知道需要进行几次的循环,有时也把for循环称为计数循环。for的语法有如下两种 : 语法一 : for 变量 in 值1 值2 值3 … do 程序 done 这种语法中 for 循环的次数,取决于in后面值的个数(空格分隔),有几个值就循环几次,并且每次循环都把值赋予变量。也就是说,假设in后面有三个值,for 会循环三次,第一次循环会把值 1 赋予变量,第二次循环会把值 2 赋予变量,依次类推。 语法二 : for (( 初始值 ;循环控制条件 ;变量变化 )) do 程序 done 语法二中需要注意 : 初始值 :在循环开始时,需要给某个变量赋予初始值,如 i = 1; 循环控制条件 :用于指定变量循环的次数,如 i <= 100,则只要i的值小于等于100,循环就会继续; 案例6 :
#!/bin/bash
cd /root/sh/
ls *.tar.gz > tar.log
ls * .tgz >> tar.log & >/dev/null
aa=$( cat tar.log | wc -l )
for (( i = 1; i <= "$aa"; i=i+1 ))
do
bb=$( cat tar.log | awk 'NR=='$i' {print $1}' )
tar -zxvf $bb -C /root/sh
done
案例7 :
#!/bin/bash
cd /root/sh/
ls *.tar.gz > tar.log
ls *.tgz >> tar.log &>/dev/null
ls *.tar.bz2 >> tar.log &>/dev/null
for i in $( cat tar.log )
do
tar -zxvf $i
done
rm -rf tar.log
案例8 :
#!/bin/bash
grep "^[0-9]\{1,3}\.[0-9]\{1,3}\.[0-9]\{1,3}\.[0-9]\{1,3\}$" /root/ip.txt > /root/ip_test1.txt
#先通过正则,把明显不符合规则的ip过滤,把结果保存在ip_test1.txt临时文件中
line=$( wc -l /root/ip_test1.txt | awk '{print $1}' )
# 统计 test1中有几行IP
echo "" >/root/ip_test.txt
#清空最终数据文件
for (( i=1; i<=$line;i=i+1 ))
#有几行,循环几次
do
cat/root/ip_test1.txt | awk 'NR=='$i'{print}' >/root/ip_test2.txt #第几次循环,就把第几行读入 ip_test2.txt文件(此文件中只有一行IP)
a=$( cat /root/ip_test2.txt | cut -d '.' -f 1 )
b=$( cat /root/ip_test2.txt | cut -d '.' -f 2 )
c=$( cat /root/ip_test2.txt | cut -d '.' -f 3 )
d=$( cat /root/ip_test2.txt | cut -d '.' -f 4 )
#分别把IP地址的四个数值分别读入变量a、b、c、d
if [ "$a" -lt 1 -o "$a" -gt 255 ]
#如果第一个数值小于1或大于等于255
then
continue
#则退出本次循环
fi
if [ "$b" -lt 0 -o "$b -gt 255 ]
then
continue
fi
if[ "$c" -lt 0 -o "$c" -gt 255 ]
then
continue
fi
if [ "$d" -lt 0 -o "$d" -gt 255 ]
then
continue
fi
#依次判断四个ip数值是否超出范围,如果超出,退出本次循环
cat /root/ip_test2.txt >> /root/ip_test.txt
#如果四个IP数值都符合要求,则把合法IP记录在文件中
done
rm -rf /root/ip_test1.txt