【LinuxShell】Shell编程之sed与awk

这篇具有很好参考价值的文章主要介绍了【LinuxShell】Shell编程之sed与awk。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


一、sed编辑器

1.sed编辑器概念

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

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

2.sed编辑器工作流程

  sed 的工作流程主要包括读取执行显示三个过程:

    读取:sed从输入流(文件、管道、标准输入〉中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。
    执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则临时sed命令将会在所有的行上依次执行
    显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空

  在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

  注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出。

处理大文件较卡问题

  流编辑器处理大文件比较卡可以使用两种方式来处理。sped命令将大文件分成若干个小文件读取。或者使用cat命令读取全部文件放在临时缓冲区中,然后交给流编辑器(grep、sed、awk)进行处理,由于使用car命令时IO消耗比较低。

3.sed编辑器用法

命令格式

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

sed -e 'n{				#n意为:指定行
操作l
操作2
...
}' 文件1 文件2 ...

常用选项

选项 含义
-e--expression= 表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用。
-f--file= 表示用指定的脚本文件来处理输入的文本文件。
-h--help 显示帮助。
-n--quietsilent 禁止sed编辑器输出,但可以与p命令一起使用完成输出。
-i 直接修改目标文本文件。

常用操作

操作 含义
s 替换,替换指定字符。
d 删除,删除选定的行。
a 增加,在当前行下面增加一行指定内容。
i 插入,在选定行上面插入一行指定内容。
c 替换,将选定行替换为指定内容。
y 字符转换,转换前后的字符长度必须相同。
p 打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容,如果有非打印字符,则以ASCII码输出。其通常与-n选项一起使用。
= 打印行号。
l(小写L) 打印数据流中的文本和不可打印的AscII字符(比如结束符$、制表符\t)

常用方式

打印内容
[root@localhost ~]# sed -n -e 'p' testfile1			#打印内容

[root@localhost ~]# sed -n -e '=' testfile1			#打印行号

[root@localhost ~]# sed -n -e 'l' testfile1			#打印隐藏特殊符号

[root@localhost ~]# sed -n -e '=;p' testfile1		#打印行号和内容
[root@localhost ~]# sed -n -e '=' -e 'p'testfile1	#打印行号和内容

sed编辑器的寻址方式

  • 以数字形式表示行区间
  • 用文本模式来过滤出行
[root@localhost ~]# sed -n '1p' testfile1					#打印第1行

[root@localhost ~]# sed -n '$p' testfile1					#打印最后一行

[root@localhost ~]# sed -n '1,3p' testfile1					#打印1到3行

[root@localhost ~]# sed -n '3,$p' testfile1					#从第3行开始打印,直到最后一行结束

[root@localhost ~]# sed -n '1,+3p' testfile1				#打印第1行之后的连续3行,即1-4行

[root@localhost ~]# sed '5q' testfile1						#打印前5行信息后退出,q表示退出

[root@localhost ~]# sed -n 'p;n' testfile1					#打印奇数行,n表示移动到下一行
[root@localhost ~]# sed -n '3{p;n;n;p}' testfile1			#打印第3,5行

[root@localhost ~]# sed -n 'n;p' testfile1					#打印偶数行
	
[root@localhost ~]# sed -n '2,${n;p}' testfile1				#从第2行开始,从下一行开始打印,即第3、5、7行

[root@localhost ~]# sed -n '/user/p' /etc/passwd			#打印包含user的行

[root@localhost ~]# sed -n '/^a/p' /etc/passwd				#打印以a开头的行

[root@localhost ~]# sed -n '/bath$/p' t/etc/passwd			#打印以bath结尾的行

[root@localhost ~]# sed -n '/ftp\|root/p' /etc/passwd		#打印含有ftp或者root的行
[root@localhost ~]# sed -nr '/ftp|root/p' /etc/passwd		#-r表示支持扩展正则表达式

[root@localhost ~]# sed -n '2,/nobody/p' /etc/passwd		#打印从第2行开始,直到第一个包含nobody的行结束

[root@localhost ~]# sed -n '2,/nobody/=' /etc/passwd		#打印从第2行开始,直到第一个包含nobody的行结束的行号

[root@localhost ~]# sed -nr '/ro{1,}t/p' /etc/passwd		#打印包含root的行,root中o的个数可以是1个以上
删除行内容
[root@localhost ~]# sed 'd' testfile1						#全删

[root@localhost ~]# sed '3d' testfile1						#删除第3行

[root@localhost ~]# sed '2,4d' testfile1					#删除第2到4行

[root@localhost ~]# sed '$d' testfile1						#删除最后一行

[root@localhost ~]# sed '/^$/d' testfile1					#删除空行

[root@localhost ~]# sed '/nologin$/d' /etc/passwd			#删除以nologin结尾的文件

[root@localhost ~]# sed '/nologin$/!d' /etc/passwd			#"!"表示取反

[root@localhost ~]# sed '/2\|3/d' testfile2					#删除第2行和第3行
[root@localhost ~]# sed '/2/,/3/d' testfile2				#从第一个位置打开行删除功能,到第二个位置关闭行删除功能
[root@localhost ~]# sed '/1/,/3/d' testfile2				#从第一个包含1的行打开删除功能,到第一个包含3的行关闭删除功能,然后接着往下扫描重复之前操作,若包含3的行不存在,则一删到底。
替换内容

命令格式

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

替换标记

数字 表明新字符串将替换第几处匹配的地方
g 表明新字符串将会替换所有匹配的地方
p 打印与替换命令匹配的行,与-n一起使用
w 文件 将替换的结果写到文件中

使用方式

[root@localhost ~]# sed -n 's/root/admin/p' /etc/passwd					#将匹配行中第一个root替换为admin然后打印替换的行
	
[root@localhost ~]# sed -n 's/root/admin/2p' /etc/passwd				#将匹配行中第二个root替换为admin然后打印替换的行

[root@localhost ~]# sed -n 's/root/admin/gp' /etc/passwd				#将匹配行所有root替换为admin然后打印替换的行
[root@localhost ~]# sed -n 's/root/admin/gw file' /etc/passwd			#将匹配行所有root替换为admin然后保存替换的行至file
[root@localhost ~]# sed -n 's/root/admin/gp' /etc/passwd > file			#将匹配行所有root替换为admin然后保存替换的行至file

[root@localhost ~]# sed 's/root//g' /etc/passwd							#将匹配行所有root替换为空的

[root@localhost ~]# sed 'l,20 s/^/#/' /etc/passwd						#在第1到20行进行注释
[root@localhost ~]# sed '/^root/ s/$/#/' /etc/passwd					#将以root开头的行进行注释

[root@localhost ~]# sed '/root/ s/^/#/' /etc/passwd						#将包含root的行进行注释
[root@localhost ~]# sed -rn 's /.*root.*/#&/p' /etc/passwd				#用正则匹配行内容,然后通过&获取前面匹配的内容进行注释后打印

[root@localhost ~]# sed -f script.sed testfile2							#对某个文件执行指定命令文件

[root@localhost ~]# sed '1,20w out.txt' /etc/passwd
[root@localhost ~]# sed '1,20 s/^/#/w out.txt' /etc/passwd				#将文件的第1到20行进行注释,然后将修改的行内容保存至指定文件

[root@localhost ~]# sed -n 's/\/bin\/bash/\/bin\/csh/p' /etc/passwd		#将文件中/bin/bash替换为/bin/csh,然后打印替换的行
[root@localhost ~]# sed -n 's!/bin\/bash!/bin\/csh!p' /etc/passwd		#使用"!"作为字符串分隔符,可以使用除了斜杠的其他字符
[root@localhost ~]# sed -i 's9\945\9\99\98\939' /etc/passwd				#将94599替换为9893
插入内容

基本使用

[root@localhost ~]# sed '/45/c ABC' testfile2							#将含有45的行都替换为ABC

[root@localhost ~]# sed 'y/145/ABC/' testfile2							#使所有的1字符转换成a,所有的2字符转换成B,所有的3字符转换成c

[root@localhost ~]# sed 'l,3a ABC' testfile2							#在第1行到第3行后都插入ABC新的一行

[root@localhost ~]# ed 'li ABC' testfile2								#在第一行前插入ABC新的一行

[root@localhost ~]# sed '5r /etc/resolv.conf' testfile2					#在第5行读取/etc/resolv.conf文件

保持空间的使用

[root@localhost ~]# sed '/root/{H;d};$G’ /etc/passwd					#将包含root的行剪切到末尾,H表示复制到剪切板,G表示粘贴到指定行后

[root@localhost ~]# sed '1,2H;3,4G' /etc/passwd						#将1、2行复制到3和4行的下面

高级使用(sed分组概念)

[root@localhost ~]# echo "111222333" | sed -r 's/(111)(222)/\2\1/'		#将字符111和 222互换位置
[root@localhost ~]# echo "111222333" | sed -r 's/^(.)(.*)(.)$/\3\2\1/'	#将第一个字符和最后一个字符互换

二.awk编辑器

1.概念

  sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个"字段"然后再进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。

  在使用awk命令的过程中,可以使用逻辑操作符 &&表示与、||表示或、!表示非;还可以进行简单的数学运算,如+-*/%^分别表示加、减、乘、除、取余和乘方。

2.工作原理

  逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。

3.用法

命令格式

awk 选项 '模式或条件 {操作}' 文件1 文件2 ...
awk -f 脚本文件 文件l 文件2 ...

常见的内建变量

内建变量 含义
FS 列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与-F作用相同。
NF 当前处理的行的字段个数。$NF代表最后一个字段。
NR 当前处理的行的行号(序数)。
$0 当前处理的行的整行内容。
$n 当前处理行的第n个字段(第n列)。
FILENAME 被处理的文件名。
RS 行分隔符。awk从文件上读取资料时,将根据Rs的定义把资料切割成许多条记录,而awk比较倾向于将一行分成多个一次仅读入一条记录,以进行处理。预设值是\n

常用方式

按行输出文本

输出所有内容

[root@localhost opt]# awk '{print}' testfile1 
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
[root@localhost opt]# awk '{print $0}' testfile1 
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve

输出指定行内容

###输出第1行内容
[root@localhost opt]# awk 'NR==1 {print}' testfile1 
one

###输出第3行内容
[root@localhost opt]# awk 'NR==3 {print}' testfile1 
three

###输出第1~3行内容
[root@localhost opt]# awk 'NR==1,NR==3 {print}' testfile1 
one
two
three
[root@localhost opt]# awk '(NR>=1)&&(NR<=3){print}' testfile1
one
two
three

###输出第1行、第3行的内容
[root@localhost opt]# awk 'NR==1||NR==3 {print}' testfile1 
one
three

输出奇偶数行的内容

###输出偶数行的内容
[root@localhost opt]# awk '(NR%2)==0{print}' testfile1 
two
four
six
eight
ten
twelve

###输出奇数行的内容
[root@localhost opt]# awk '(NR%2)==1{print}' testfile1 
one
three
five
seven
nine
eleven

输出含有字符串的行

###输出含有root的行
[root@localhost opt]# awk '/root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

###输出以root开头的行
[root@localhost opt]# awk '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

###输出以nologin结尾的行
[root@localhost opt]# awk '/nologin$/{print}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
...
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin

统计以/bin/bash 结尾的行数

[root@localhost opt]# awk 'BEGIN {x=0};/\/bin\/bash$/{x++};END {print x}' /etc/passwd
2

此命令等同于grep -c "/bin/bash$" /etc/passwd

BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作;awk再处理指定的文本,之后再执行END模式中指定的动作,END{}语句块中,往往会放入打印结果等语句。

按字段输出文本

输出每行中(以控股或制表位分隔)的第3个字段

[root@localhost opt]# awk -F":" '{print $3}' /etc/passwd
0
1
2
3
4
5
6
...
38
42
29
65534
98
74
70
89
72
1000

输出每行中的第1、3个字段

[root@localhost opt]# awk -F":" '{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
...
geoclue 989
ntp 38
gdm 42
rpcuser 29
nfsnobody 65534
gnome-initial-setup 988
sshd 74
avahi 70
postfix 89
tcpdump 72
tang 1000

输出特定条件的行的字段内容

###输出第3个字段的值小于5的第1、3个字段内容
[root@localhost opt]# awk -F":" '$3<5{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4

###输出第3个字段不小于200的行
[root@localhost opt]# awk -F":" '!($3<200){print $1,$3}' /etc/passwd
polkitd 999
libstoragemgmt 998
colord 997
saned 996
gluster 995
saslauth 994
setroubleshoot 993
chrony 992
unbound 991
sssd 990
geoclue 989
nfsnobody 65534
gnome-initial-setup 988
tang 1000

###输出第3个字段大于等于1000的行,用if语句进行判断
[root@localhost opt]# awk 'BEGIN{FS=":"};{if($3>=1000){print}}' /etc/passwd
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
tang:x:1000:1000:tang:/home/tang:/bin/bash

使用三元运算符输出内容

如果第3个字段的值大于等于第4个字段的值,则把第3个字段的值赋给max,否则第4个字段的值赋给max

[root@localhost opt]# awk -F":" '{max=($3>=$4)?$3:$4;{print max}}' /etc/passwd
0
1
2
4
7
5
6
7
12
11
100
50
99
192
81
999
998
997
32
996
995
994
173
993
172
171
75
992
991
107
59
990
113
989
38
42
29
65534
988
74
70
89
72
1000

输出每行内容和行号

每处理完一条记录,NR值加1

[root@localhost opt]# awk -F":" '{print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
17 libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
18 colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
19 rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
20 saned:x:996:993:SANE scanner daemon user:/usr/share/sane:/sbin/nologin
21 gluster:x:995:992:GlusterFS daemons:/run/gluster:/sbin/nologin
22 saslauth:x:994:76:Saslauthd user:/run/saslauthd:/sbin/nologin
23 abrt:x:173:173::/etc/abrt:/sbin/nologin
24 setroubleshoot:x:993:990::/var/lib/setroubleshoot:/sbin/nologin
25 rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
26 pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
27 radvd:x:75:75:radvd user:/:/sbin/nologin
28 chrony:x:992:987::/var/lib/chrony:/sbin/nologin
29 unbound:x:991:986:Unbound DNS resolver:/etc/unbound:/sbin/nologin
30 qemu:x:107:107:qemu user:/:/sbin/nologin
31 tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
32 sssd:x:990:984:User for sssd:/:/sbin/nologin
33 usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
34 geoclue:x:989:983:User for geoclue:/var/lib/geoclue:/sbin/nologin
35 ntp:x:38:38::/etc/ntp:/sbin/nologin
36 gdm:x:42:42::/var/lib/gdm:/sbin/nologin
37 rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
38 nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
39 gnome-initial-setup:x:988:982::/run/gnome-initial-setup/:/sbin/nologin
40 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
41 avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
42 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
43 tcpdump:x:72:72::/:/sbin/nologin
44 tang:x:1000:1000:tang:/home/tang:/bin/bash

输出两种指定条件的内容

###输出以冒号分隔且第7个字段中包含/bash的行的全部内容
[root@localhost opt]# awk -F":" '$7~"/bash"{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
tang:x:1000:1000:tang:/home/tang:/bin/bash

###输出以冒号分隔且第7个字段中包含/bash的行的第1个字段
[root@localhost opt]# awk -F":" '$7~"/bash"{print $1}' /etc/passwd
root
tang

###输出第1个字段中包含root且有7个字段的行的第1、2个字段
[root@localhost opt]# awk -F":" '($1~"root")&&(NF==7){print $1,$2}' /etc/passwd
root x

###输出第7个字段既不为/bin/bash,也不为/sbin/nologin的所有行
[root@localhost opt]# awk -F":" '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
通过管道、双引号调用 Shell命令

统计以冒号分隔的文本段落数,END{}语句块中,往往会放入打印结果等语句。

每处理完一条记录,NR值加1

[root@localhost opt]# echo $PATH | awk 'BEGIN {RS=":"}; END{print NR}'
5

调用wc -l命令统计使用bash 的用户个数

[root@localhost opt]# awk -F: '/bash$/{print | "wc -l"}' /etc/passwd
2
[root@localhost opt]# awk -F: '/bash$/{print}' /etc/passwd | wc -l
2

此命令等同于grep -c "bash$" /etc/passwd

查看当前内存使用百分比

[root@localhost opt]# free -m | awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'
33%
[root@localhost opt]# free -m | awk '/Mem:/ {print $3/$2 * 100"%"}'
24.1379%

查看当前CPU空闲率

[root@localhost opt]# top -b -n 1 | awk -F"," '/%Cpu/ {print $4}' | awk '{print $1}'
100.0
[root@localhost opt]# top -b -n 1 | grep Cpu | awk -F ',' '{print $4}' | awk '{print $1}'
100.0

-b -n 1表示只需要1次的输出结果。

查看当前磁盘的情况

###查看当前磁盘的使用率
[root@localhost opt]# df | awk '$NF=="/" {print $5}'
13%
###查看当前磁盘的空闲率
[root@localhost opt]# df | awk '$NF=="/" {print $5}' | awk -F% '{print 100-$1"%"}'
87%

显示上次系统重启时间

[root@localhost opt]# date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"
2023-05-15 08:44:02
[root@localhost opt]# date -d "$(cat /proc/uptime | awk -F. '{print $1} ' ) second ago" +"%Y-%m-%d %H:%M:%S"
2023-05-15 08:44:02

常见日期用法

###当月第一天
[root@localhost opt]# date +%Y%m01
20230501

##下个月第一天
[root@localhost opt]# date -d "1 month" +%Y%m01
20230601

###上个月第一天
[root@localhost opt]# date -d "-1 month" +%Y%m01
20230401
[root@localhost opt]# date -d "1 month ago" +%Y%m01
20230401

###明天
[root@localhost opt]# date -d "1 day" +%Y%m%d
20230516

##昨天
[root@localhost opt]# date -d "-1 day" +%Y%m%d
20230514
[root@localhost opt]# date -d "yesterday" +"%Y%m%d" 
20230514

###上个月最后一天
[root@localhost opt]# date -d "$(date +%Y%m01) -1 day" +%Y%m%d
20230430

###当月最后一天
[root@localhost opt]# date -d "$(date -d "1 month" +%Y%m01) -1 day" +%Y%m%d
20230531

面试题:每个月最后一天去执行指定文件

方式1:脚本中进行判断
###当月最后一天
lastday=$(date -d "$(date -d "1 month" + "%Y%m01") -1 day" +"%Y%m%d")
###今天
today=$(date +%Y%m%d)
###判断今天是否是最后一天
if [ "$today" == "$lastday" ];then 执行文件

方式2:计划性任务中判断
0 0 28-31 if [ "$(date -d "$(date -d "1 month" + "%Y%m01") -1 day" +"%Y%m%d")" == "today=$(date +%Y%m%d)"];then 执行文件

调用w命令,并用来统计在线用户数

[root@localhost opt]# awk 'BEGIN{n=0;while("w" | getline) n++ ;{print n-2}}'
2

调用hostname,并输出当前的主机名

[root@localhost opt]# awk 'BEGIN{"hostname" | getline ;{print $0}}'
localhost.localdomain

获取奇偶数行

###获取偶数行
[root@localhost opt]# seq 10 | awk '{getline;print $0}'
2
4
6
8
10

###获取奇数行
[root@localhost opt]# seq 10 | awk '{print $0;getline}'
1
3
5
7
9

getline左右无重定向符<|时,awk首先读取到了第一行,就是1,然后使用getline就得到了1下面的第二行,就是2,因为getline之后,awk会改变对应的NFNRFNR$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来。

getline左右有重定向符<|时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。

查看使用特定分隔符的字符串

###输出A B C D字符串
[root@localhost opt]# echo "A B C D"
A B C D

###输出ABCD字符串以及用|分隔的字符串
[root@localhost opt]# echo "A B C D" | awk '{OFS="|";print $0;$1=$1;print $0}'
A B C D
A|B|C|D

###输出以逗号分隔的ABCD字符串
[root@localhost opt]# echo "A B C D" | awk 'BEGIN{OFS=","};{$2=$2;print $0}'
A,B,C,D
echo "A B C D" | awk '{print $1","$2","$3","$4}'
A,B,C,D

OFS是列输出分隔符,可以用来指定分隔符。

$1=$1是用来激活$0的重新赋值,也就是说字段$1…和字段数NF的改变会促使awk重新计算$0的值,通常是在改变OFS后而需要输出$0时这样做。

按数组输出文本以及统计

下标是数字时输出文本

[root@localhost opt]# awk 'BEGIN{a[0]=10;a[1]=20;print a[1]}'
20
[root@localhost opt]# awk 'BEGIN{a[0]=10;a[1]=20;print a[0]}'
10

下标是一串字符时输出文本

[root@localhost opt]# awk 'BEGIN{a["abc"]=10;a["xyz"]=20;print a["abc"]}'
10
[root@localhost opt]# awk 'BEGIN{a["abc"]=10;a["xyz"]=20;print a["xyz"]}'
20

其中字符串需要用双引号包起来。

下标是数字,使用循环输出文本

[root@localhost opt]# awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a){print a[1]}}'
20
20
20
[root@localhost opt]# awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a){print a[2]}}'
30
30
30

其中BEGIN中的命令只执行一次

通过数组统计重复行的数量

[root@localhost opt]# cat test.txt
aaa
aaa
bbb
ccc
aaa
bbb
aaa
###统计重复字符串的数量以及输出对应的字符串
[root@localhost opt]# awk '{a[$1]++}END{for(i in a){print a[i],i}}' test.txt 
4 aaa
1 ccc
2 bbb
###从大到小排序
[root@localhost opt]# awk '{a[$1]++}END{for(i in a){print a[i],i}}' test.txt |sort -r
4 aaa
2 bbb
1 ccc

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

统计登录失败的ip地址出现的次数文章来源地址https://www.toymoban.com/news/detail-441904.html

[root@localhost log]# cat /var/log/secure | awk '/Failed password/{print $11}' | sort -n |uniq -c
      3 192.168.145.30
      1 192.168.145.45

[root@localhost log]# cat /var/log/secure | awk '/Failed password/{a[$11]++}; END{for(i in a){print a[i],i}}'
1 192.168.145.45
3 192.168.145.30

到了这里,关于【LinuxShell】Shell编程之sed与awk的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Sed编辑器

    目录 sed编辑器 命令格式: 常用选项: 常用操作: 打印内容: 使用地址: ​编辑 替换:  插入: sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,

    2024年02月05日
    浏览(67)
  • sed编辑器基础命令

    shell脚本编程系列 学习sed编辑器 sed编辑器被称作流编辑器(stream editor),与普通的交互式文本编辑器不同,在交互式文本编辑器可以用键盘命令交互式插入、删除或替换文本数据。流编辑器则是根据事先设计好的一组规则编辑数据流。 sed编辑器主要操作 从输入中读取一行数

    2024年02月01日
    浏览(26)
  • DAY 35 sed文本编辑器

    文本三剑客:都是按行读取后处理。 grep 过滤行内容 awk 过滤字段 sed 过滤行内容;修改行内容 sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流 sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存

    2023年04月19日
    浏览(32)
  • Linux文本之sed流编辑器

    目录 一、sed的相关知识及其工作流程 1)sed编辑器的介绍 2)sed 流编辑器的工作过程 3)怎么解决sed命令处理容量过大,或则内容过多的而导致执行效率慢的问题? 解决方案一(推荐用法): 解决方案二: 二、sed命令格式与选项操作符 1)sed命令格式  基本操作格式:  2)

    2024年02月04日
    浏览(27)
  • 文本三剑客之sed编辑器

    Sed是一个强大的文本处理工具,其名称是Stream Editor(流编辑器)的缩写。它被设计用于根据用户定义的规则对文本进行逐行处理和转换。 Sed通过从输入流中逐行读取文本,并根据用户指定的命令来对每一行进行处理 sed的工作原理是 逐行读取 输入文本,并根据用户 指定的命

    2024年02月12日
    浏览(33)
  • 【Linux命令行与Shell脚本编程】第十八章 文本处理与编辑器基础

    文本处理 学习sed编辑器 sed编辑器基础命令 gawk编辑器入门 sed编辑器基础 shell脚本可以将文本文件中各种数据的日常处理任务自动化Linux中的sed和gawk两款工具能够极大地简化数据处理任务。 想要即时处理文本文件中的文本,有一个可以自动格式化、插入、修改或删除文本元素

    2024年02月13日
    浏览(34)
  • Linux文本处理工具sed(流编辑器)

    sed是一种流编辑器,它一次处理一行内容。 处理时,把当前处理的行存储在临时缓冲区(模式空间)中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送到屏幕。接着处理下一行,这样不断重复直到文件末尾。 文件内容并没有改变 ,除非你使用重定向存

    2024年02月12日
    浏览(49)
  • Linux Shell 脚本编程学习之【第2章 Linux文件系统和文本编辑器(第一部分)】

    1、root用户 系统唯一,是真实的。该用户既可以登录系统,可 以操作系统任何文件和命令,拥有最高权限。 2、虚拟用户 这类用户也被称为伪用户或假用户,与真实用户区分开来,这类用户不 具有登录系统的能力,但却是系统运行不可缺少的用户,比如 bin、daemon、adm、 ft

    2024年02月16日
    浏览(39)
  • Linux:概述 、安装 、文件与目录结构 、vim编辑器 、网络配置 、远程登录 、系统管理 、基础命令 、软件包管理 、克隆虚拟机 、shell编程

    2.1.1、Linux是什么? Linux是一个操作系统(OS) 所谓的操作系统就是直接用来操作计算机底层硬件的软件。 2.1.2、Linux的出现 官网: https://www.centos.org/ 进入官网进行下载 有很多的镜像,以阿里云的为例: 3.3.1、下载 官网: https://www.vmware.com/ 这是下载的企业版,30天试用期,可

    2024年02月05日
    浏览(51)
  • Linux和Shell笔记-6使用编辑器Vim

    对文本在编辑器的功能(如查找,剪切和粘贴)了解越多,编写shell脚本的速度就越快。以VIM为例 安装vim vim基础 键入vim(或vi,如果这个别名或链接文件存在的话)如 vim有两种操作模式,普通模式和插入模式 普通模式将按键解释成命令 插入模式将光标位置输入的每个键插入

    2024年02月16日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包