shell正则表达式:sedawk 之文本三剑客其二

Posted kiroct

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell正则表达式:sedawk 之文本三剑客其二相关的知识,希望对你有一定的参考价值。

sed编辑器

sed是一种流编辑器,流编辑器会在编辑器处理之前基于预先提供的一组规则来编辑流数据。

sed编辑器可以根据命令来处理流数据中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本当中。

sed的工作流程主要包括:

读取、执行、和显示三个过程

读取:sed从输入流(文件、管道、标准输入)中读取一行内容并存储在临时的缓冲区中(又称模式空间)

执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将在所有行上依次执行。

显示:发送修改后的内容到输出流,在发送数据后,模式空间将会被清空。在所有文件内容都被处理完成之前,上述过程中将重复执行直至所有内容被处理完。

在所有内容都被处理完成之前,上述过程将重复执行,直至所有内容都被处理完成。ps:默认情况下的所有sed命令都是在完成模式空间内执行的,因此输入的文件不会发生任何变化,除非是用重定向输出的。

命令格式:

sed -e 操作 文件1 文件2 .....

sed -n -e 操作 文件1 文件2 ....
sed -f 脚本文件 文件1 文件2 ....

sed -i -e 操作 文件1 文件2 .....

sed -e n

操作1

操作2

...

文件1 文件2 ...

常用选项:

-e:表示用指定命令来处理输入的文件文件。只有一个操作命令时可省略,一般在执行多个操作命令使用

-f:表示用指定的脚本文件来处理输入的文本文件

-h:显示帮助

-n: --quit或者silent: 禁止esd编辑器输出,但可以与p命令一起使用完成输出

-i : 直接修改目标文本文件

常用操作:

s : 替换,替换指定字符

d:删除,删除选定的行

a: 增加,在当前行下面增加一行指定内容

i: 插入,在选定行上面插入一行指定内容

c:替换,将选定行替换成指定内容

y:字符替换,转换前后的字符长度必须相同

p:打印。如果同时指定行,表示打印指定行,:如果不指定行,则表示打印所有内容,如果有非打印字符。则以ASCII码输出。通常与"-n"选项一起使用

= :打印行号

l(小写的L):打印数据流中的文本和不可打印的ASCII字符(比如$、\\t)

打印内容:

sed -n -e p testfile1
sed -n -e = testfile1
sed -n -e l testfile1
sed -n -e =;p testfile1
sed -n -e = -e p testfile1

sed -n
>=
> p
>  testfile

使用编辑地址:

sed编辑器有两种寻址方式:

1、以数字形式表示行区间

2、用文本模式来过滤出行

sed -n  1p testfile1
sed -n $p testfilel
sed -n 1,3p testfile1
sed -n 3,$p testfilel
sed -n 3,$p testfilel     #打印1之后的连续3行,即1-4行
sed 5q testfilel           #打印前5行信息后退出,q表示退出
sed -n p;n testfile1       sed -n p;n testfile1
sed -n p;n testfile1       sed -n p;n testfile1

sed编辑:器有2种寻址方式:

1、以数字形式表示行区间

2、用文本模式来过滤出行

sed -n 1p testfile1

sed -n $p testfilel

sed -n 1,3p testfile1

sed -n 3,$p testfilel

sed -n  1, +3p testfile1                   #打印1之 后的连续3行,即1-4行

sed 5q testfile1                           #打印前5行信息后退出,q表示退出

sed -n p;n testfile1                        #打印奇数行: n表示移动到下- - 行

sed -n n;p testfilel                           #打印偶数行

sed -n 2,$n;p testfilel

sed -n  /user/p /etc/passwd

sed -n /^a/p /etc/passwd

sed -n  /bash$/p /etc/passwd

sed -n  /ftp\\lroot/p /etc/passwd

删除行:

sed d testfile1 #全删

sed 3d testfilel

sed 2,4d testfile1

sed $d testfile1

sed /^$/d testfile1 #删除空行

sed /nologin$/!d /etc/passwd #“!”表示取反操作

sed /2/,/3/d testfile2 #从第--个位置打开行删除功能,到第二个sed /1/,/3/d testfile2

替换:

行范围s/旧字符串/新字符串/替换标记

4种替换标记:

数字:表明新字符串将替换第几处匹配的地方

g:表明新字符串将会替换所有匹配的地方

p: 打印与替换命令匹配的行,与-n- -起使用

w文件:将替换的结果写到文件中

sed -n s/root/ admin/p /etc/ passwd

sed -n s/root/ admin/2p /etc/passwd

sed -n s/root/ admin/gp /etc/passwd

sed s/root//g /etc/ passwd

sed 1,20 s/^/#/ /etc/passwd

sed /^root/ s/$/#/ /etc/passwd

sed -rn s/. *root.*/#&/p /etc/passwd

sed -f script.sed testfile2

插入:

sed /45/c ABC testfile2

sed y/145/ABC/ testfile2                   #使所有的1字符转换成A,所有的2字符转换成B,所有的3字符转换成C

sed 1,3a ABC testfile2

sed 1i ABC testfile2

sed 5r /etc/ resolv.conf testfile2

sed /root/ H;d;$G /etc/passwd           #将包含root的行剪切到末尾,H表示复制到剪切板,G表示粘贴到指定行后

sed 1,2H;3, 4G /etc/passwd                 #将1、2行复制到3和4行的下面

echo "111222333" 1 sed -r s/(111) (222)/\\2\\1/ #将字符111和222 互换位置,

echo "111222333" 1 sed -r s/^(.) (.*) (.)$/\\3\\2\\1/            #将第-“个字符和最后- -个字符互换

sed实验

实验:使用p来打印显示脚本的内容


实验:使用sed编辑器打印出行号

实验:打印出影藏的阿斯科码

实验:使用;来合并2个命令

此外也可以使用此种方式来打

实验:打印行号;1p、1,3p一至三行、$p尾行

补充:打印出1-3行且最后一行

打印前3行后退出,q表示退出

打印第一行,然后再打印接下来的三行

打印奇数行


打印偶数行

$确定行的区间,2-表示最后一行,然后执行n;p(读取偶数行),不读取第二行打印的3、5、7、9奇数行


打印以G开头的文件内容

打印出etc/passwd文件中以/bin/bash结尾的内容

sed -nr 表示直接支持正则表达式

删除空行

sed -n s 替换第一个root后面单跟一个p;表示只替换第一个,跟两个p代表替换第二个。而gp代表替换全部!

AWK 使用

AWK命令(基本用法:行的输出和列的输出)

工作原理:

逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。sed命令常用于一- 整行的处理,而awk比较倾向于将一行 分成多个“字段"然后再进行处理。awk信 息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。在使用awk命令的过程中,可以使用逻辑操作符“&"表示“与”、“11”表示“或”、“!”表示"非”:还可以进行简单的数学运算,如+、 -、*、1、号、^分别表示加、减、乘、除、取余和乘方。

命令格式:

awk 选项 模式条件 {操作} 文件1 文件2 ...

awk -f 脚本文件 文件1 文件2 .....

awk常见的内建变量

FS:列分隔符。指定每行文本的字段分割,默认为空格或者制表位,与"-F"作用相同
NF:当前处理行的行号字段个数
NR:当前处理行的行号(序号)
$0: 当前处理的行的整行内容。
$n:当前处理行的第n个字段(第n列)。
FILENAME:被处理的文件名。
RS:行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk-次仅读入--条记录,以进行!

按行输出文本:

awk print testfile2       #输出所有内容

awk  print $O testfile2    #输出所有内容

awk NR==1, NR==3print testfile2                #输出第1~3行内容

awk  (NR>=1)&& (NR<=3) print testfile2     #输出第1~3行内容

awk NR==1 |NR==3print testfile2               #输出第1行、第3行内容

awk  (NR82)=-1print testfile2                       #输出所有奇数行的内容

awk  (NR82)==0print testfile2                      #输出所有偶数行的内容

  awk /^root/print /etc/passwd                   #输出以root 开头的行

awk  /nologin$/ print /etc/passwd            #输出以nologin 结尾的行

awk BEGIN x=0;/\\/bin\\/bash$/x++;END print x /etc/passwd    #统计以/bin/bash结尾的行数,等同于grep -c

"/bin/bash$" /etc/passwd                      

BEGIN模式表示, 在处理指定的文本之前,需要先执行BEGIN模式中指定的动作: awk再处理指定的文本,之后再执行END模式中指定的动作

END语句块中,往往会放入打印结果等语句

按字段输出文本:

awk -F ":” print $3 /etc/passwd                  #输出每行中(以空格或制表位分隔)的第3个字段

awk -F ":” $3<5print $1,$3 /etc/passwd    #输出第3个字段的值小于5的第1、3个字段内容                           

awk -F ":" ! ($3<200) print /etc/passwd        #输出第3个字段的值不小于200的行

awk BEGIN FS=":";|if ($3>=1000) print /etc/passwd #先处理完BEGIN的内容, 再打印文本里面的内容

awk -F ":"  max= ($3>=$4) ?$3:$4; print max /etc/passwd

($3>$4) ?$3:$4;三元运算符, 如果第3个字段的值大于等于第4个字段的值,则把第3个字段的值赋给max,否则第4个字段的值赋给max

awk -F ":" print NR,$0 /etc/passwd    #输出每行内容和行号,每处理完--条记录,NR值加1

awk -F ":" $7~" /bash"print $1 /etc/passwd    #输出以冒号分隔且第7个字段中包含/bash的行的第1个字段

awk -F”:”  ($1~"root")&& (NE==7) print $1,$2 /etc/passwd #输出第1个字段中包含root且有7个字段的行的第1、2个字段  

awk -F ":"  ($7!="/bin/bash")&& ($7!="/sbin/nologin") print /etc/passwd

#输出第7个字段既不为/bin/bash, 也不为/ sbin/nologin的所有行

通过管道、双引号调用Shell 命令:

echo $PATH 1 awk  BEGINRS=":";ENDprint NR            #统计以冒号分隔的文本段落数,END语句块中,往往会放入打印结果等语句

awk -F: " /bash$/print | "wc -1" /etc/passwd/etc/ passwd     #调用wc -1命令统计使用bash的用户个数,等同于grep -c "bash$"

free -m 1 awk /Mem:/ print int ($3/ ($3+$4)*100)"%" #查看当前内存使用百分比

top -b -n 1 | grep Cpu | awk -F , print $4 | awk print $1    #查看当前CPU空闲率,(-b -n 1表示只需要1次的输出结果)

date -d "$(awk -F "." print $1 /proc/uptime) second ago" +"%F 8H: 8M: 8S"
#显示上次系统重启时间,等同于uptime; second ago为显示多少秒前的时间,+"8F &H: 8M:号S"等同于+"8Y-8m-8d 8H:号M: 8S"的时间格式
date +"8Y8m01"                当月第一天

awk BEGIN n=0 ; while ("w" | getline) n++ ; print n-2                #调用w命令,并用来统计在线用户数

awk BEGIN ("hostname" | getline ; print $0                      #调用hostname, 并输出当前的主机名

seq 10 I awk  getline; print $0                   #获取偶数行

seq 10 1 awk print $0; getline                   #获取基数行

当getline左右无重定向符“<”或“1”时,awk首 先读取到了第- -行, 就是1,然后getline, 就得到了1下面的第二行,就是2,因为getline之后,awk会改变对应的NF, NR, FNR和$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来。当getline左右有重定向符“<"或" |"时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入- -行,只是getline读入那么getline返回的是该文件的第一行, 而不是隔行。

FNR: awk 当前读取的记录数,其变量值小于等于NR (比如当读取第二个文件时,FNR是从0开始重新计数,而NR不会)。NR==FNR: 用于在读取两个或两个以上的文件时,判断是不是在读取第一 一个文件

CPU使用率

cpu_ _us=top -b -n 1 1 grep Cpu 1 awk  print $2 ‘

cpu_ sy=top -b -n 1 1 grep Cpu 1 awk -F , print $2 1 awk print $1

cpu_ sum=$ (($cpu_ _us+$cpu_ sy))

echo $cpu sum

echo "A B C D”I awk OFS="|";print $0;$1=$1;print $0

ABCD

AIBICID

$1=$1是用来激活$0的重新赋值,也就是说

字段$1...和字段数NF的改变会促使awk重新计算$0的值,通常是在改变OFS后而需要输出$0时这样做

awk BEGINa[0]=10;a[1]=20; print a[1]

awk BEGINa[0]=10;a[1]=20; print a[0

awk BEGINa["abc"]=10;a["xyz"]=20;print a["abc"]

awk BEGINa["abc"]=10;a["xyz"]=20;print a["xyz"]

awk BEGINa["abc" ]="aabbcc";a["xyz"]="xxyyzz";print a["xyz"]

awk BEGINa[0]=10;a[1]=20;a[2]=30;for(i in a)print i,a[i]

PS1: BEGIN中的命令只执行一- 次

PS2: awk数组的下标除了可以使用数字,也可以使用字符串,字符串需要使用双引号

cat test. txt

aaa

aaa

bbb

ccc

aaa

bbb

aaa

awk a[1]++ENDfor(i in a) print a[i] test. txt

PS: a[1]初始为0,a[1]++后即为1, 而这里awk中的a [1]++最终的值是由test.txt文本内容有多少行决定的,文本逐行读取完毕后再执行END中的命令

awk a[$1]++ENDfor(i in a) print a[i] test.txt | sort -r

使用awk统计httpd 访问日志中每个客户端IP的出现次数?

答案:

awk ip[$1] ++ENDfor(i in ip) print ip[i],i /var/log/httpd/access_ log 1 sort -r

备注:定义数组,数组名称为ip,数字的下标为日志文件的第1列(也就是客户端的IP地址),++的目的在于对客户端进行统计计数,客户端

IP出现- - 次计数器就加1。END中 的指令在读取完文件后执行,通过循环将所有统计信息输出,for 循环遍历的是数组名ip的下标。

BEGIN模式中的命令只执行一次

awk中数组的下标和元素的值都可以是数字,也可是字符串,字符串需要用双引号括起来

awk数组的数组名保存的是下 标的列表,相对应的元素的值使用数组名[下标]来表示

awk a[$1]++; END for(i in a)print i,a[il test.txt 1 sort -t -k2 -nr

a[$1]++; $1代表的是文件的第一 列内容 并且awk 会逐行读取文件内容,a[$1]初始值为0, 当awk匹配到- -行相同内容后就会自增加1

也就是说a[$1] 的值取决于$1在文件中的此列中出现的次数,而$1的值都保存在数组a中

END for(i in a)print i,a[i] END模式的操作是在awk处理完文件内容后再执行的操作

for循环中的变量i用于遍历获取数组a的值(也就是说是$1的值),print i相当于把$1列中不同的值进行去重后输出

AWK使用实验

输出内容,$0是全部,$1是第一行,$2是第二行,以此推类

输出一至五行的内容
或者

比较passwd中第三列uid和第四列uid的号数值的大小,输出大的

如果etc/passwd第三字段大于或者等于200,就输出该行

如果第三字段大于第四字段,就输出第三字段,不大于则输出第四字段

输出每行的内容(给每行标号,NR行号)

通过管道,双引号使用shell命令

输出路径环境变量 通过管道符号交给awk
BEGIN先处理{}的内容

统计以/bash结尾的个数

查看cpu空闲率,top -b -n 1表示在top中以1查看cpu的使用率

查看内容使用率,先用awk找MEM,然后int进行整数运算,最后记得加上字符串"%"

调用"w"指令,统计在线用户人数

调用hostname,输出当前主机名

seq发送1-10行。getline获取2、4、6、8、10,print获取1、3、5、7

seq发送1-10行。getline获取2、4、6、8、10,print获取1、3、5、7

以上是关于shell正则表达式:sedawk 之文本三剑客其二的主要内容,如果未能解决你的问题,请参考以下文章

shell编程-正则表达式与文本处理器sedawk

五三剑客之sedawk

linux12shell编程 --> 三剑客之grep命令

Shell编程之正则表达式

Shell编程之正则表达式三剑客——awk工具

shell脚本编程之正则表达式(扩展正则表达式sed)