shell编程知识点

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<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/hosts文件中读取文件内容进行赋值


数组循环

for 循环遍历数组(hosts是上面赋值的hosts)


运行结果


for 循环读取/etc/hosts中的文件


统计 /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键


awk 'BEGIN{print 1/2} {print "ok"} END {print "Game Over"}' /etc/hosts


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]}}'



你可能感兴趣的:(shell编程知识点)