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中,文件分界符(通常写成EOF,你也可以写成FOE或者其他任何字符串)紧跟在<<符号后,意思是分界符后的内容将被当做标准输入传给<<前面的命令,直到再次在独立的一行遇到这个文件分界符(EOF或者其他任何字符,注意是独立一行,EOF前面不能有空格)。通常这个命令是cat,用来实现一些多行的屏幕输入或者创建一些临时文件。
把输出追加到文件
root@ribbonchen-laptop:~# cat<<EOF>out.txt
脚本实现了一个简单的菜单功能:
批量打包:
使用格式基本是这样的:
命令 << 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.批量量获取在线主机, 进⾏行行秘钥批量量分发
10.循环控制
1.for 循环基础语法
2.for 案例例, 批量量探测主机存活状态
3.for 循环批量量创建⽤用户
5.for 循环通过⽂文件批量量创建⽤用户
6.批量量修改密码
2.While循环语句句
3.Shell内置命令
exit 退出整个程序
break 结束当前循环,或跳出本层循环
continue 忽略略本次循环剩余的代码,直接进⾏行行下⼀一次循环
11.Shell函数应⽤用
1.定义函数:
//⽅方式⼀一
函数名() {
函数要实现的功能代码
}
//⽅方式⼆二
function 函数名 {
函数要实现的功能代码
}
2.调用函数和函数传参:
//调⽤用函数
function_name 即可调⽤用函数
//函数传参
fun $1 传⼊入脚本后第⼀一个参数
fun $* 接收所有参数的传递
3.函数返回
4.位置参数
5.数组传参
12.数组
1.定义数组:
//⼀一次赋多个值,数组名=(多个变量量值)
[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
2.关联数组
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
3.遍历数组
1.通过数组元数的个数进⾏行行遍历(不不推荐)
2.通过数组元数的索引进⾏行行遍历(推荐)
注意: 将统计的对象作为数组的索引, 仅针对关联数据
1.数据赋值和遍历
数组循环
统计 /etc/passwd 的 shell 数量量
统计 Nginx ⽇日志 IP 访问次数
统计 tcp 的状态信息
13.正则表达式
文件内容:
//过滤以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
14.sed⽂文本处理
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
删除⽂文件
14.Awk⽂文本处理理
awk 是⼀一种编程语⾔言,⽤用于在 linux/unix 下对⽂文本和数据进⾏行行处理理。
awk 数据可以来⾃自标准输⼊入、⼀一个或多个⽂文件,或其它命令的输出。
awk 通常是配合脚本进⾏行行使⽤用, 是⼀一个强⼤大的⽂文本处理理⼯工具。
awk 的处理理⽂文本和数据的⽅方式如下:
1.进行逐行扫描⽂文件, 从第一行到最后⼀行
2.寻找匹配的特定模式的行,在行上进行操作
3.如果没有指定处理理动作,则把匹配的⾏行行显示到标准输出
4.如果没有指定模式,则所有被操作的⾏行行都被处理理
1.awk 的两种形式语法格式
awk [options] 'commands' filenames
awk [options] -f awk-script-file filenames
options
-F 定义输⼊入字段分隔符,默认的分隔符是空格或tab键
2.awk命令格式
3.Awk ⼯工作原理理
# 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 中,覆盖原来的内容,然后将新的字符串串分隔成字段并进⾏行行处理理。该过程将持续到所有⾏行行处理理完毕
4.Awk内部变量量
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 格式化输出函数
5.Awk模式动作
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
6.Awk条件判断
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]}}'