1.函数
(1) 函数可以这样定义:
function fname()
{
statements;
}
或者
fname()
{
statements;
}
甚至是这样(对于简单的函数):
fname() { statement; }
(2) 只需使用函数名就可以调用函数:
$ fname ; #执行函数
(3) 函数参数可以按位置访问
$1是第一个参数,$2是第二个参数,以此类推:fname arg1 arg2 ; #传递参数
2.读取命令返回值(状态)
命令的返回值被保存在变量$?中。
cmd;
echo $?;
返回值被称为退出状态。它可用于确定命令执行成功与否。如果命令成功退出,那么退出状
态为0,否则为非0。
3.比较与测试
程序中的流程控制是由比较语句和测试语句处理的。Bash能够执行各种测试。我们可以用if、if else以及逻辑运算符来测试,用比较运算符来比较数据项。除此之外,还有一个test命令也可以用于测试
if-then是条件选择语句,及根据if后面的条件的执行情况在决定程序的执行流程。
test可以提高if-then的条件判断能力,test命令中列出的条件如果成立,则test命令就会退出且返回退出状态码0。
如果test后面没有任何内容则返回非0,因此可以用来简单判断变量是否为空
另外一种方法为使用 方括号[ ],比如:
if [ $value -gt 5 ]
表示测试变量是否大于5。但是在脚本中用于字符串比较的>必须加上转义字符,否则会被识别为重定向符号。
对比字符串只能使用==、<、>、!=、-z、-n。对比字符串时,末尾一定要加上x(或者a、b等)一个字符,因为if [ $1x == "ab"x ]时如果没有了x ,并且$1是"",这个语句会翻译成if [ == "ab" ],左边相当于没有东西了,会报语法错误。或者使用[[ ]],就不需要x了。使用<或者>时,如果是用[ ],需要用转义符"\",如\>。
对比数字使用既能使用-eq、-ne、-gt、-ge、-lt、-le,也能使用==、<、>、!=。其中-eq的意思是equal,-ne是unequal,-gt是greater than,-ge是greater than or equal to,-lt是less than,-le是less than or equal to
使用正则表达式
if在对比时可以使用正则表达式,如if [[ $1 == a*a ]](或者if [ $1x == a*ax ])。如果使用""把a*a包围起来,*就会变成字符*,而不是正则表达式中的*。
[和[[的区别
区别一。在[中使用逻辑运算符,需要使用-a(and)或者-o(or)。在[[中使用逻辑运算符,需要使用&&或者||。
区别二。[是shell命令,在它包围的表达式是它的命令行参数,所以串比较符>和<需要转义,否则就变成io重定向了。[[是shell关键字,不会做命令行扩展,所以<和>不需要进行转义。但是语法相对严格,如在[中可以用引号括起操作付,[[则不行。如if [ "-z" "ab" ]。
区别三。[[可以做算术扩展,[则不行。如if [[ 11+1 -eq 100 ]],而if [ 11+1 -eq 100 ]则会报错。
文件判断
在高级语言中,判断文件是否存在等各种状态都是需要调用特定的函数进行判断。而在shell中,这方面就比较方便些,只需要运算符即可。
常用的文件判断运算符如下:
-e 文件是否存在
-f 文件是否是普通文件(不是目录、设备文件、链接文件)
-s 表示文件大小不为0
-d 表示文件是否是目录
-b 表示是块设备(光驱、软盘等)
-c 表示是字符设备(键盘、声卡等)
-p 表示是管道
-h 表示是符号链接
-S 表示是否是socket
-r、-w、-x表示文件是否有可读、可写、可执行权限(指运行这个测试命令的用户)
f1 -nt f2 f1是否比f2新(new than)
f1 -ot f2 f1是否比f2旧(old than)
f1 -ef f2 f1和f2是否是相同文件的硬链接
4.变量
1.)自动定义变量
1.定义变量量 :变量量名=变量量值 ,不不允许数字命名, 不不能使⽤用横岗命名
2.引⽤用变量量 :$变量量名 或 ${变量量名}
3.查看变量量 :echo $变量量名 set显示所有变量量,包括⾃自定义变量量和环境变量量
4.取消变量量 :unset 变量量名 作⽤用范围:仅在当前 shell 中有效
2.)系统环境变量
1.定义环境变量量 :export export 变量量 ,将⾃自定义变量量转换成环境变量量
2.引⽤用环境变量量 :$变量量名 或 ${变量量名}
3.查看环境变量量 :echo $变量量名 env |grep Name
4.取消环境变量量 :unset 变量量名
5.变量量作⽤用范围 :在当前shell和⼦子shell有效
3.)位置参数变量量
脚本参数传参: $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
4.)预先定义变量量
$0 脚本⽂文件名
$* 所有的参数
$@ 所有的参数
$# 参数的个数
$$ 当前进程的 PID
$! 上⼀一个后台进程的 PID
$? 上⼀一个命令的返回值 0 表示成功
5.) 变量量赋值⽅方式
a.显式赋值(变量量名=变量量值) a = 3
b.read 从键盘读⼊入变量量值
read 变量量名
read -p "提示信息: " 变量量名
read -t 5 -p "提示信息: " 变量量名
read -n 2 变量量名
注意事项: 定义或引⽤用变量量时注意事项: " " 弱引⽤用 ' ' 强引⽤用
c.``命令替换等价于 $() 反引号中的 shell 命令会被先执⾏行
[root@bgx ~]# touch `date +%F`_file1.txt
[root@bgx ~]# touch $(date +%F)_file2.txt
[root@bgx ~]# disk_free3="df -Ph |grep '/$' |awk '{print $4}'"
[root@bgx ~]# disk_free4=$(df -Ph |grep '/$' |awk '{print $4}')
[root@bgx ~]# disk_free5=`df -Ph |grep '/$' |awk '{print $4}'`
5.变量量数值运算
1.整数运算 expr + - \* / %
expr 1 + 2
expr $num1 + $num2
2.整数运算 $(()) + - * / %
echo $(($num1+$num2))
echo $((num1+num2))
echo $((5-3*2))
echo $(((5-3)*2))
echo $((2**3))
sum=$((1+2)); echo $sum
3.整数运算 $[] + - * / %
echo $[5+2]
echo $[5**2]
4.整数运算 let + - * / %
let sum=2+3;
echo $sum
5.⼩小数运算 bc + - * / %
echo "2*4" |bc
echo "2^4" |bc
echo "scale=2;6/4" |bc
awk 'BEGIN{print 1/2}'
echo "print 5.0/2" |python
6.变量量删除替换
1.从前往后删除变量量内容
url=www.sina.com.cn
//获取变量量值的⻓长度
[root@bgx ~]# echo ${#url}
//输出变量url
[root@bgx ~]# echo ${url}
//从前往后,最短匹配
[root@bgx ~]# echo ${url#*.}
//从前往后,最⻓长匹配(贪婪匹配)
[root@bgx ~]# echo ${url##*.}
2.从后往前删除变量量内容
//从后往前,最短匹配
[root@bgx ~]# echo ${url%.*}
//从后往前,最⻓长匹配 贪婪匹配
[root@bgx ~]# echo ${url%%.*}
[root@bgx ~]# echo ${url#a.}
[root@bgx ~]# echo ${url#*sina.}
3.索引及切⽚片
[root@bgx ~]# echo ${url:0:5}
[root@bgx ~]# echo ${url:5:5}
[root@bgx ~]# echo ${url:5}
4.变量量内容替换
[root@bgx ~]# url=www.sina.com.cn
[root@bgx ~]# echo ${url/sina/baidu}
[root@bgx ~]# url=www.sina.com.cn
[root@bgx ~]# echo ${url/n/N}
//贪婪匹配
[root@bgx ~]# echo ${url//n/N}
5.变量量替代
${变量量名-新的变量量值}
变量量没有被赋值:会使⽤用“新的变量量值“ 替代
变量量有被赋值(包括空值): 不不会被替代
//例例1
取消url变量
[root@Shell day01]# unset url
[root@Shell day01]# echo $url
6.变量量替代(同5)
${变量量名:-新的变量量值}
变量量没有被赋值(包括空值): 都会使⽤用“新的变量量值“ 替代
变量量有被赋值: 不不会被替代
7.变量量⾃自增
[root@bgx ~]# unset i
[root@bgx ~]# unset j
[root@bgx ~]# i=1
[root@bgx ~]# j=1
[root@bgx ~]# let x=i++ 先赋值,再运算
[root@bgx ~]# let y=++j 先运算,再赋值
//对变量量值不不会产⽣生任何影响
[root@bgx ~]# echo $i
2
[root@bgx ~]# echo $j
2
//对表达式的值的影响
[root@bgx ~]# echo $x
1
[root@bgx ~]# echo $y
2
对变量量的值的影响:
[root@bgx ~]# i=1
[root@bgx ~]# let i++
[root@bgx ~]# echo $i 2
案例:
8.⽂文件测试
https://www.cnblogs.com/fulucky/p/8027024.html
[ -e dir|file ]
[ -d dir ] 是否存在,⽽而且是⽬目录
[ -f file ] 是否存在,⽽而且是⽂文件
[ -r file ] 读权限
[ -x file ] 执⾏行行权限
[ -w file ] 写权限
1.常⻅见使⽤用⽅方式
[ ! -d /bbb ] && mkdir /test
[ -d /bbb ] || mkdir /test
2.脚本使⽤用⽅方式
2.数值⽐比较
数值⽐比较 [ 整数 1 操作符 整数 2 ]
[ 1 -gt 10 ] ⼤大于
[ 1 -lt 10 ] ⼩小于
[ 1 -eq 10 ] 等于
[ 1 -ne 10 ] 不不等于
[ 1 -ge 10 ] ⼤大于等于
[ 1 -le 10 ] ⼩小于等于
1.条件测试, 脚本使⽤用案例例, 创建⽤用户
2.查看磁盘/当前使⽤用状态,如果使⽤用率超过80%则报警发邮件
//怎么看磁盘使⽤用率,怎么获取对应的值
df -h|grep "/$"|awk '{print $5}'|awk -F '%' '{print $1}'
/怎么进⾏行行数值⽐比对
3.查看内存/当前使⽤用状态,如果使⽤用率超过80%则报警发邮件
Mem_Total=$(free -m|grep "^M"|awk '{print $2}')
Mem_Use=$(free -m|grep "^M"|awk '{print $3}')
Mem_B=$((($Mem_Use*100)/$Mem_Total))
if [ $Mem_B -ge 30 ];then
echo -e "\033[31m Memory Is Err ${Mem_B}% \033[0m"
else
echo -e "\033[32m Memory Is OK ${Mem_B}% \033[0m"
fi
3.字符串串⽐比较
1.字符串串⽐比对
//⼩小结:变量量为空 或未定义: ⻓长度都为0
2.多整数⽐比对条件
3.正则⽐比对
4.判断⽤用户输⼊入的是否是数字
5.批量量创建⽤用户脚本, 仅个⼈人使⽤用
9.流程控制
1.单分⽀支结构
2.双分⽀支结构
3.多分⽀支结构
3.流程控制语句句case
4.批量删除⽤用户
shell中的cat和文件分界符(< 在shell中,文件分界符(通常写成EOF,你也可以写成FOE或者其他任何字符串)紧跟在<<符号后,意思是分界符后的内容将被当做标准输入传给<<前面的命令,直到再次在独立的一行遇到这个文件分界符(EOF或者其他任何字符,注意是独立一行,EOF前面不能有空格)。通常这个命令是cat,用来实现一些多行的屏幕输入或者创建一些临时文件。 把输出追加到文件 root@ribbonchen-laptop:~# cat< 脚本实现了一个简单的菜单功能: 批量打包: 使用格式基本是这样的: 命令 << EOF 内容段 EOF 将“内容段”整个作为命令的输入。 你的代码里就是用cat命令读入整段字符串并赋值给list变量。 Here document Here Document 是在Linux Shell 中的一种特殊的重定向方式,它的基本的形式如下: cmd << delimiter Here Document Content delimiter 它的作用就是将两个 delimiter 之间的内容(Here Document Content 部分) 传递给cmd 作为输入参数 这里要注意几点 1.EOF 只是一个标识而已,可以替换成任意的合法字符 2.作为结尾的delimiter一定要顶格写,前面不能有任何字符 3.作为结尾的delimiter后面也不能有任何的字符(包括空格) 4.作为起始的delimiter前后的空格会被省略掉 5.Here Document 不仅可以在终端上使用,在shell 文件中也可以使用,例如下面的here.sh 文件 5.expect 定义变量量实现交互⽅方式 6.expect 进⾏行行参数传递,执⾏行行命令或其他操作 7.批量量获取在线主机, 进⾏行行秘钥批量量分发 2.for 案例例, 批量量探测主机存活状态 3.for 循环批量量创建⽤用户 5.for 循环通过⽂文件批量量创建⽤用户 6.批量量修改密码 exit 退出整个程序 break 结束当前循环,或跳出本层循环 continue 忽略略本次循环剩余的代码,直接进⾏行行下⼀一次循环 1.定义函数: //⽅方式⼀一 函数名() { 函数要实现的功能代码 } //⽅方式⼆二 function 函数名 { 函数要实现的功能代码 } 2.调用函数和函数传参: //调⽤用函数 function_name 即可调⽤用函数 //函数传参 fun $1 传⼊入脚本后第⼀一个参数 fun $* 接收所有参数的传递 3.函数返回 4.位置参数 5.数组传参 //⼀一次赋多个值,数组名=(多个变量量值) [root@Shell ~]# array2=(tom jack alice) [root@Shell ~]# array3=(tom jack alice "bash shell") [root@Shell ~]# array4=(1 2 3 "linux shell" [20]=puppet) //针对每个索引进⾏行行赋值 [root@Shell ~]# array1[0]=pear [root@Shell ~]# array1[1]=apple [root@Shell ~]# array1[2]=orange [root@Shell ~]# array1[3]=peach 2.访问数组 //统计数组元数的个数 [root@Shell ~]# echo ${#array1[@]} 4 //访问数组中的第⼀一个元素 [root@Shell ~]# echo ${array1[0]} pear //从数组索引1开始 [root@Shell ~]# echo ${array1[@]:1} apple orange peach //从数组索引1开始,访问两个元素 [root@Shell ~]# echo ${array1[@]:1:2} apple orange //访问数组中所有数据,相当于echo ${array1[*]} [root@Shell ~]# echo ${array1[@]} pear apple orange peach 3.获取数组索引 [root@Shell ~]# echo ${!array1[@]} 0 1 2 3 1.定义关联数组, 申明是关联数据 [root@Shell ~]# declare -A tt_array_1 [root@Shell ~]# declare -A tt_array_2 2.给关联数组进⾏行行赋值 数组名[索引]=变量量值 [root@Shell ~]# tt_array1[index1]=pear [root@Shell ~]# tt_array1[index2]=apple [root@Shell ~]# tt_array1[index3]=orange [root@Shell ~]# tt_array1[index4]=peach //给关联数组⼀一次赋多个值 [root@Shell ~]# tt_array2=([index1]=tom [index2]=jack [index3]=alice [index4]='bash shell') 3.查看关联数组 [root@Shell ~]# declare -A 4.访问数据元数 //访问数组中的第⼆二个元数 [root@Shell ~]# echo ${tt_array2[index2]} jack //访问数组中所有元数 等同于 echo ${array1[*]} [root@Shell ~]# echo ${tt_array2[@]} bash shell tom jack alice //访问数组中所有元数的索引 [root@Shell ~]# echo ${!tt_array2[@]} index4 index1 index2 index3 1.通过数组元数的个数进⾏行行遍历(不不推荐) 2.通过数组元数的索引进⾏行行遍历(推荐) 注意: 将统计的对象作为数组的索引, 仅针对关联数据 1.数据赋值和遍历 数组循环 统计 /etc/passwd 的 shell 数量量 统计 Nginx ⽇日志 IP 访问次数 统计 tcp 的状态信息 文件内容: //过滤以m开头的行 [root@Shell ~]# grep "^m" test.txt //过滤以m结尾的行 [root@Shell ~]# grep "m$" test.txt //排除空⾏行行, 并打印⾏行行号 [root@student ~]# grep -vn "^$" xuliangwei.txt //匹配任意⼀一个字符,不不包括空⾏行行 [root@student ~]# grep "." xuliangwei.txt //.匹配所有 [root@student ~]# grep ".*" xuliangwei.txt //匹配单个任意字符 [root@node1 ~]# grep "xuliangw.i" xuliangwei.txt //以点结尾的 [root@student ~]# grep "\.$" xuliangwei.txt //精确匹配到 [root@student ~]# grep -o "8*" xuliangwei.txt //匹配有abc的⾏行行 [root@student ~]# grep "[abc]" xuliangwei.txt //匹配数字所在的⾏行行"[^0-9]" [root@student ~]# grep "[0-9]" xuliangwei.txt //匹配所有⼩小写字⺟母[^a-z] [root@student ~]# grep "[a-z]" xuliangwei.txt //重复0三次 [root@student ~]# grep "8\{3\}" xuliangwei.txt //重复3个000不不⽤用转义符 [root@student ~]# grep -E "8{3}" xuliangwei.txt //重复数字8, 3-5次 [root@student ~]# grep -E "8{3,5}" test.txt //⾄至少1次或1次以上 [root@student ~]# grep -E "8{1,}" xuliangwei.txt https://blog.csdn.net/koozxcv/article/details/51455750 sed是⼀一个流编辑器器, ⾮非交互式的编辑器器,它⼀一次处理理⼀一⾏行行内容. 处理理时,把当前处理理的⾏行行存储在临时缓冲区中,称为“模式空间”(pattern space) 接着⽤用 sed 命令处理理缓冲区中的内容,处理理完成后, 把缓冲区的内容送往屏幕。 接着处理理下⼀一⾏行行,这样不不断重复,直到⽂文件末尾。 ⽂文件内容并没有改变,除⾮非你 使⽤用重定向存储输出。 Sed 要⽤用来⾃自动编辑⼀一个或多个⽂文件;简化对⽂文件的反复操作;编写转换程序等 1.sed命令形式 sed [options] 'command' file(s) 2.sed 和正则使用 与 grep⼀一样,sed 在⽂文件中查找模式时也可以使⽤用正则表达式(RE)和各种元字符。 正则表达式是括在斜杠间的模式,⽤用于查找和替换,以下是sed⽀支持的元字符。 使⽤用基本元字符集 , $, ., *, [], [], < >, (), {} 使⽤用扩展元字符集 ?, +, { }, |, ( ) 使⽤用扩展元字符的⽅方式 + sed -r 3.sed命令形式 sed 对指定⾏行行进⾏行行操作,包括打印、删除、修改、追加等。 sed选项参数 -e 允许多项编辑 -n 取消默认的输出 -i 直接修改对应⽂文件 -r ⽀支持扩展元字符 sed 命令参数 a 在当前⾏行行后添加⼀一⾏行行或多⾏行行 c 在当前⾏行行进⾏行行替换修改 d 在当前⾏行行进⾏行行删除操作 i 在当前⾏行行之前插⼊入⽂文本 p 打印匹配的⾏行行或指定⾏行行 n 读⼊入下⼀一输⼊入⾏行行,从下⼀一条命令进⾏行行处理理 ! 对所选⾏行行以外的所有⾏行行应⽤用命令 h 把模式空间⾥里里的内容重定向到暂存缓冲区 H 把模式空间⾥里里的内容追加到暂存缓冲区 g 取出暂存缓冲区的内容,将其复制到模式空间,覆盖该处原有内容 G 取出暂存缓冲区的内容,将其复制到模式空间,追加在原有内容后⾯面 多重编辑选项 e: //先删除行,然后管道给后⾯面的sed进⾏行行替换,passwd是文件 [root@Shell ~]# sed '1,9d' passwd | sed 's#root#alex#g' //使⽤用-e进⾏行行多次编辑修改操作 [root@Shell ~]# sed -e '1,9d' -e 's#root#alex#g' passwd 打印命令 p: //打印匹配halt的⾏,/匹配内容/p [root@Shell ~]# sed -n '/halt/p' passwd //打印第⼆二⾏行行的内容 [root@Shell ~]# sed -n '2p' passwd //打印最后⼀一⾏行行 [root@Shell ~]# sed -n '$p' passwd 追加命令 a: //给30⾏行行添加配置 \t tab键(需要转义) \n 换⾏行行符 [root@Shell ~]# sed -i '30a listen 80;' out.txt 修改命令 c //指定某⾏行内容替换 [root@Shell ~]# sed -i '7c SELINUX=Disabled' /etc/selinux/config //正则匹配对应内容, 然后进⾏行行替换 sed -i '/^SELINUX=/c SELINUX=Disabled' /etc/selinux/config //非交互式修改指定的配置⽂文件 [root@Shell ~]# sed -ri '/UseDNS/cUseDNS no' /etc/ssh/sshd_config [root@Shell ~]# sed -ri '/GSSAPIAuthentication/c#GSSAPIAuthentication no' /etc/ssh/ sshd_config [root@Shell ~]# sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config 文件替换: //s表示替换命令,/my/表示匹配my,/Hao Chen’s/表示把匹配替换成Hao Chen’s,/g 表示一行上的替换所有的匹配 sed "s/my/Hao Chen's/g" pets.txt //重定向文件: $ sed "s/my/Hao Chen's/g" pets.txt > hao_pets.txt //在每一行最前面加点东西:在每行之前加# sed 's/^/#/g' pets.txt //在每一行最后面加点东西:在每行之后加--- sed 's/$/ --- /g' pets.txt //指定行需要替换的内容:指定第三行 sed "3s/my/your/g" pets.txt //只替换第3到第6行的文本 sed "3,6s/my/your/g" pets.txt //只替换每一行的第一个s: sed 's/s/S/1' my.txt //只替换每一行的第二个s: sed 's/s/S/2' my.txt //只替换第一行的第3个以后的s: sed 's/s/S/3g' my.txt //多次匹配 第一个模式把第一行到第三行的my替换成your,第二个则把第3行以后的This替换成了That sed -e '1,3s/my/your/g' -e '3,$s/This/That/g' my.txt 删除命令 d //指定删除第三⾏行行, 但不不会改变⽂文件内容 [root@Shell ~]# sed '3d' passwd [root@Shell ~]# sed '3{d}' passwd //从第三⾏行行删除到最后⼀一⾏行行 [root@Shell ~]# sed '3,$d' passwd //删除最后⼀一⾏行行 [root@Shell ~]# sed '$d' passwd //删除所有的⾏行行 [root@Shell ~]# sed '1,$d' passwd //匹配正则进⾏行行该⾏行行删除,删除mail这一行 [root@Shell ~]# sed /mail/d passwd 插⼊入命令 i //在文件的某一行上⾯添加内容,30表示行 [root@Shell ~]# sed -i '30i listen 80;' passwd 写⽂文件命令 w //将匹配到的⾏行行写⼊入到新⽂文件中,newfile是新文件,/root/是匹配字符 [root@Shell ~]# sed -n '/root/w newfile' passwd //将passwd⽂文件的第⼆二⾏行行写⼊入到newfile中 [root@Shell ~]# sed -n '2w newfile' passwd 获取下⼀一⾏行行命令 n //匹配root的行, 删除root行的下一列 [root@Shell ~]# sed '/root/{n;d}' passwd //替换匹配root⾏行行的下⼀一列列 [root@Shell ~]# sed '/root/{n; s/bin/test/}' passwd 暂存和取⽤用命令 h H g G //将第⼀一⾏行行的写⼊入到暂存区, 替换最后⼀一⾏行行的内容 [root@Shell ~]# sed '1h;$g' /etc/hosts //将第⼀一⾏行行的写⼊入到暂存区, 在最后⼀一⾏行行调⽤用暂存区的内容 [root@Shell ~]# sed '1h;$G' /etc/hosts //将第⼀一⾏行行的内容删除但保留留⾄至暂存区, 在最后⼀一⾏行行调⽤用暂存区内容追加⾄至于尾部 [root@Shell ~]# sed -r '1{h;d};$G' /etc/hosts //将第⼀一⾏行行的内容写⼊入⾄至暂存区, 从第⼆二⾏行行开始进⾏行行重定向替换 [root@Shell ~]# sed -r '1h;2,$g' /etc/hosts //将第⼀一⾏行行重定向⾄至暂存区, 2-3⾏行行追加⾄至暂存区, 最后追加调⽤用暂存区的内容 [root@Shell ~]# sed -r '1h; 2,3H; $G' /etc/hosts 反向选择命令 //除了了第三⾏行行,其他全部删除 [root@Shell ~]# sed -r '3!d' /etc/hosts sed匹配替换 s 替换命令标志 g ⾏行行内全局替换 i 忽略略替换⼤大⼩小写 替换命令 s 删除⽂文件 awk 是⼀一种编程语⾔言,⽤用于在 linux/unix 下对⽂文本和数据进⾏行行处理理。 awk 数据可以来⾃自标准输⼊入、⼀一个或多个⽂文件,或其它命令的输出。 awk 通常是配合脚本进⾏行行使⽤用, 是⼀一个强⼤大的⽂文本处理理⼯工具。 awk 的处理理⽂文本和数据的⽅方式如下: 1.进行逐行扫描⽂文件, 从第一行到最后⼀行 2.寻找匹配的特定模式的行,在行上进行操作 3.如果没有指定处理理动作,则把匹配的⾏行行显示到标准输出 4.如果没有指定模式,则所有被操作的⾏行行都被处理理 awk [options] 'commands' filenames awk [options] -f awk-script-file filenames options -F 定义输⼊入字段分隔符,默认的分隔符是空格或tab键 # awk -F: '{print $1,$3}' /etc/passwd 1.awk使⽤用⼀一⾏行行作为输⼊入,并将这⼀一⾏行行赋给内部变量量 $0 每⼀一⾏行行也可称为⼀一个记录,以换⾏符结束 2.awk进⾏行行字段分解,每个字段存储在已编号的变量量中,从 $1 开始 3.awk默认情况下的分隔符是空格, 是由内部变量量 FS 来确定字段分隔符。初始 FS 为空格 4.awk打印字段,将以设置的⽅方法使⽤用 print 函数打印 5.awk在打印的字段间加上空格,因为 $1,$3 之间有⼀一个逗号。逗号它映射为另⼀一个内部变 量量,称为输出字段分隔符 OFS 默认为空格 6.awk输出之后,将从⽂文件中获取另⼀一⾏行行,并将其存储在 $0 中,覆盖原来的内容,然后将新的字符串串分隔成字段并进⾏行行处理理。该过程将持续到所有⾏行行处理理完毕 1.$0 保存当前记录的内容 [root@Shell ~]# awk '{print $0}' /etc/passwd 2.NR 控制输⼊入的总⾏行行数 //打印整个⽂文本的⾏行行号 [root@Shell ~]# awk '{print NR,$0}' /etc/passwd //打印文件的前三行 [root@Shell ~]# awk 'NR<=3' /etc/passwd 3.FNR 记录输⼊文件的编号 [root@Shell ~]# awk '{print FNR,$0}' /etc/passwd /etc/hosts 4.NF 保存⾏行行的最后⼀一列列内容 [root@Shell ~]# awk -F ":" '{print $1,$NF}' /etc/passwd 5.FS 指定字段分割符,默认空格 //以冒号作为字段分隔符 [root@Shell ~]# awk -F: '/root/{print $1, $3}' /etc/passwd [root@Shell ~]# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd //以空格冒号tab作为字段分割 [root@Shell ~]# awk -F'[ :\t]' '{print $1,$2,$3}' /etc/passwd 6.OFS 输出字段分隔符 //,映射为OFS,初始情况下OFS变量量是空格 [root@Shell ~]# awk -F: '/root/{print $1,$2,$3,$4}' /etc/passwd [root@Shell ~]# awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2}' /etc/passwd 7.RS 输入记录分隔符,默认为换行符,按照空格进行换行 [root@Shell ~]# awk -F: 'BEGIN{RS=" "} {print $0}' /etc/hosts 8.ORS 将文件每一行合并为⼀行,以空格为分割 [root@Shell ~]# awk -F: 'BEGIN{ORS=" "} {print $0}' /etc/hosts //通常情况下让输出分隔符为换行符, 然后依次打印响应的字段 [root@Shell ~]# awk -F ":" 'BEGIN{OFS="\n"}{print $1,$2,$3,$4,$5,$6,$7}' passwd //将RS记录值标记为冒号分割, 打印后相当于将每行的内容进行切割 [root@Shell ~]# awk 'BEGIN{RS=":"}{print $0}' passwd 8.print 格式化输出函数 awk语句句都由模式和动作组成。 模式部分决定动作语句句何时触发及触发事件。 如果省略略模式部分,动作将时刻保持执⾏行行状态。模式可以是条件语句句或复合语句句或正则表达式 1.正则表达式 //匹配记录(整⾏行行) [root@Shell ~]# awk '/^root/' /etc/passwd [root@Shell ~]# awk '$0 ~ /^root/' /etc/passwd //匹配字段:匹配操作符(~ !~) [root@Shell ~]# awk '!/^root/' /etc/passwd [root@Shell ~]# awk '$0 ~ !/^root/' /etc/passwd 2.比较表达式 比较表达式采用对⽂文本进行比较,只有当条件为真,才执行指定的动作。 比较表达式使用关系运算符,用于比较数字与字符串串 关系运算符 3.条件表达式 4.运算表达式 5.逻辑操作符和复合模式 //匹配⽤用户名为root并且打印uid⼩小于15的⾏行行 [root@Shell ~]# awk -F: '$1~/root/ && $3<=15' /etc/passwd //匹配⽤用户名为root或uid⼤大于5000 [root@Shell ~]# awk -F: '$1~/root/ || $3>=5000' /etc/passwd 1. if语句句格式:{ if(表达式){语句句;语句句;... }} //打印当前管理理员⽤用户名称 [root@Shell ~]# awk -F: '{ if($3==0){print $1 "is adminisitrator"} }' /etc/passwd //统计系统⽤用户数量量 [root@Shell ~]# awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd //统计普通⽤用户数量量 [root@Shell ~]# awk -F: '{ if($3>1000){i++}} END {print i}' /etc/passwd 2. if...else 语句句格式: {if(表达式){语句句;语句句;... }else{语句句;语句句;...}} 3.if...else if...else 语句句格式: {if(表达式 1){语句句;语句句;... }else if(表达式 2){语句句;语句句;. .. }else{语句句;语句句;... }} 7.Awk循环语句句 1.while循环 [root@Shell ~]# awk '{i=1; while(i<=NF){print $i; i++}}' b.txt 2.for循环 3.awk数组实战 注意:将需要统计的某个字段作为数组的索引,最后对索引进⾏行行遍历 1.按索引遍历 awk -F: '{username[++x]=$1} END{for(i in username) {print i,username[i]} }' /etc/passwd 2.统计/etc/passwd 中各种类型 shell 的数量量 awk -F: '{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }' /etc/passwd 3.⽹网站访问状态统计<当前时实状态ss> [root@Shell ~]# ss -an|awk '/:80/{tcp[$2]++} END {for(i in tcp){print i,tcp[i]}}' 4.统计当前访问的每个IP的数量量<当前时实状态 netstat,ss> [root@Shell ~]# ss -an|awk -F ':' '/:80/{ips[$(NF-1)]++} END {for(i in ips){print i,ips[i]}}' 5.统计当前访问的每个IP的数量量<当前时实状态 netstat,ss> [root@Shell ~]# ss -an|awk -F ':' '/:80/{ips[$(NF-1)]++} END {for(i in ips){print i,ips[i]}}'10.循环控制
1.for 循环基础语法
2.While循环语句句
3.Shell内置命令
11.Shell函数应⽤用
12.数组
1.定义数组:
2.关联数组
3.遍历数组
13.正则表达式
14.sed⽂文本处理
14.Awk⽂文本处理理
1.awk 的两种形式语法格式
2.awk命令格式
3.Awk ⼯工作原理理
4.Awk内部变量量
5.Awk模式动作
6.Awk条件判断