Linux基础篇学习——文件搜索工具grep,sed,awk

正则表达式

grep 正则表达式引擎

文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查、打印匹配到的行

模式:由正则表达式的元字符及文本字符所编写出的过滤条件

命令语法
grep [OPTIONS] PATTERN [FILE...]	;PATTERN 模式
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]		;可以把模式写到一个文件中通过-f读取,然后对file进行过滤
OPTION

-i忽略字符大小写
-n 打印行号
-o 仅显示匹配到的字符串
-v 显示不能匹配到的字符串
-E支持扩展正则表达式
-w严格匹配

-A num后num行
-B num前num行
-C num前后各num行

-q 静默模式,不输出任何信息
- - color=auto 匹配到的文本着色后高亮显示

1.egrep==grep -E,使用扩展的正则表达式对文本进行搜索
2.fgrep==grep -F,利用固定的字符串来对文本进行搜索
 特点:①不支持正则表达式的引用
    ②此命令的执行速度也最快

实例
  1. 匹配/etc/passwd中含有operator的及其前后各3行
[root@localhost tmp]# grep -C 3 "operator" /etc/passwd
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
  1. 匹配网卡配置文件中的含点分十进制的行
[root@zycentos7 ~]# egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=192.168.232.125
NETMASK=255.255.255.0
GATEWAY=192.168.232.2
DNS=114.114.114.114
[root@zycentos7 ~]# egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=192.168.232.125
NETMASK=255.255.255.0
GATEWAY=192.168.232.2
DNS=114.114.114.114

在这里插入图片描述

  1. 匹配邮箱
[root@zycentos7 ~]# egrep '[[:alnum:]]+@[[:alnum:]]+\.[a-z]+' c
[root@zycentos7 ~]# egrep '[a-z0-9]+@[a-z0-9]+\.[a-z]+' c
  1. 取出默认shell为bash,且其用户ID号最小的用户的用户名
[root@zycentos7 ~]# grep "bash$" /etc/passwd|sort -n -t: -k 3|head -1|cut -d: -f1
root

练习1 显示/etc/passwd文件中不以/bin/bash结尾的行
grep -v "/bin/bash$" /etc/passwd
练习2 找出/etc/passwd文件中的两位数或三位数
egrep '\<[0-9]{2,3}\>' /etc/passwd
练习3 找出/etc/rc.d/rc.sysinit或/etc/grub2.cfg文件中,以至少一个空白字符开头,且后面非空白字符的行
grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg
练习4 找出"netstat -tan"命令的结果中以’LISTEN’后跟0、1或多个空白字符结尾的行
netstat -tan | grep "LISTEN[[:space:]]*$"
练习5 找出/proc/meminfo文件中,所有以大写或小写S开头的行;至少有三种实现方式
grep -i "^s" /proc/meminfo
grep "^[sS]" /proc/meminfo
grep -E "^(s|S)" /proc/meminfo
练习6 显示当前系统上root、centos或user1用户的相关信息
grep -E "^(root|centos|user1)\>" /etc/passwd
练习7 找出/etc/rc.d/init.d/functions文件中的函数(某单词后面跟一个小括号的行)
grep -o "[_[:alnum:]]*()" /etc/rc.d/init.d/functions
练习8 使用echo命令输出一绝对路径,使用egrep取出基名
echo /etc/sysconfig/ | grep -E -o "[^/]+/?$"
取出其路径名dirname
练习9 找出ifconfig命令结果中的1-255之间的数值
ifconfig | grep -E -o "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
练习10 找出ifconfig命令结果中的IP地址
ifconfig | grep -Eo "(\<[0-9]{1,3}\>\.){3}\<[0-9]{1,3}\>"
练习11 找出/etc/passwd文件中用户名同shell名的行

[root@zycentos7 ~]# grep -E "^([^:]+\>).*\1$" /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

在这里插入图片描述
练习12 找出/etc/passwd文件中的用户名

[root@zycentos7 ~]# head -3 /etc/passwd|grep -Eo '^[^:]+'
root
bin
daemon
[root@zycentos7 ~]# head -3 /etc/passwd|grep -Eo '^[^:]{1}'
r
b
d
[root@zycentos7 ~]# head -3 /etc/passwd|grep -Eo '^[^:]{3}'
roo
bin
dae

sed

sed工作原理

模式空间 pattern space
模式空间在内存中处理文件的每个输入行

保持空间 holding space
保持空间在内存中保存已经处理过的输入行

非交互式 sed只能够在命令行下输入编辑命令来对文本进行编辑,然后在屏幕上查看输出

流式 sed每次只从文件中读入一行,然后对该行进行指定的处理,并将处理结果输出到屏幕上,处理完后在读入下一行

sed 把当前正在处理的行保存在一个临时缓存区中,这个缓存区称为模式空间或临时缓冲,sed 处理完模式空间中的行后把该行发送到屏幕上,继续处理下一行, 当处理完输入文件的最后一行后, sed 结束运行

sed 把每一行都存在模式空间中,对这个副本进行编辑,所以不会修改或破坏原文件

在这里插入图片描述

命令语法

sed [OPTION]... `script` [input-file]...

script 地址定界编辑命令 /root/p

OPTION

-n 不输出模式空间中的内容到屏幕
-e script 多点编辑
-f file 每行编辑一个命令
-r支持扩展正则表达式
-i 直接编辑原文件 慎重使用,建议先备份

示例1 sed -e script多点编辑,查找root和apache的用户相关信息

[root@zycentos7 ~]# sed -n \
> -e '/^root/ p' \
> -e '/^apache/ p' \
> /etc/passwd
root:x:0:0:root:/root:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

[root@zycentos7 ~]# sed -n '{
> /^root/ p
> /^apache/ p
> }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

示例2 sed批处理-f file,查找root和apache的用户相关信息

[root@zycentos7 ~]# cat test-script.sed
/^root/ p
/^apache/ p
[root@zycentos7 ~]# sed -nr -f test-script.sed /etc/passwd
root:x:0:0:root:/root:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

地址界定

  1. 空地址
    对全文进行处理
  2. 单地址
    # 指定行
    ^ 行首
    $ 行尾
    /pattern/ 被此模式所匹配到的每一行
    pattern/I 匹配时忽略大小写
    %pattern% 任何能够被匹配到的行%为边界符号可更改
  3. 地址范围
    #,#3,5 3-5行
    #,+#3,+5 3-8行
    #,/pat1/ 从#行开始到第一次能够被匹配到的行
    /pat1/,/pat2/ 被模式匹配到的行内的所有的行
  4. 步进:~
    1~2 所有奇数行
    2~2 所有偶数行
    1~1 所有行
    n~n 所有n的倍数行(n不等于1)

示例1 sed#,#,查找从mail开始到dbus结束的用户相关信息

[root@zycentos7 ~]# sed -nr '/^mail/,/^dbus/ p' passwd

示例2 sed步进~,每隔2行打印1行(打印3的倍数行)

[root@zycentos7 ~]# sed -nr '3~3 p' /etc/passwd
[root@zycentos7 ~]# sed -nr '3~3 =' /etc/passwd	;查看打印的行数

示例3 只查看包含log且后面有信息的行

[root@zycentos7 ~]# cat log.txt

log:input.txt

log:

log:testing resumed

log:

log:output created
[root@zycentos7 ~]# sed -n '/log:*./p' log	;错误示例
log:input.txt
log:
log:testing resumed
log:
log:output created
[root@zycentos7 ~]# sed -n '/log: *./p' log.txt
log:input.txt
log:testing resumed
log:output created

sed -n '/log:*./p' log.txt 中的 :* 匹配*前面的字符任意次,按匹配 : 0次,. 匹配任意单个字符比如 : ,所以会匹配到log后面无信息的行
sed -n '/log: *./p' log.txt 中的 * ,按匹配 0次,. 匹配任意单个字符,即log:后必须有信息

编辑命令

d 删除
p 打印模式空间中的内容
a \text 在行后面追加文本“text”
i \text 在行前面插入文本“text”
c \text 把匹配到的行替换为此处指定的文本“text”
a,c,i使用时不指定行默认所有行
w file 保存模式空间匹配到的行至指定的文件中
r file 文件合并 读取指定文件的内容至当前文件被模式匹配到的行后面
= 打印行号
 取反

示例1 删除
准备文件

[root@zycentos7 ~]# cat test
101,John Doe,CEO

102,Jason Smith,IT Manager
#103,Raj Reddy,Sysadmin

104,Anand Ram,Developer
105,Jane Miller,Sales Manager
  1. 删除空行
[root@zycentos7 ~]# sed '/^$/ d' test
101,John Doe,CEO
102,Jason Smith,IT Manager
#103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
  1. 删除开头第一个字符是 # 的行(删除注释行)
[root@zycentos7 ~]# sed '/^#/ d' test
101,John Doe,CEO

102,Jason Smith,IT Manager

104,Anand Ram,Developer
105,Jane Miller,Sales Manager
  1. 删除以#开头,且后面跟了至少一个空白字符的行的#和空白字符
[root@zycentos7 ~]# sed -nr 's/^#[[:space:]]+//gp' test

示例2 行后追加(a)、行前插入(i)、替换行(c)、文件合并(r)
准备文件

[root@zycentos7 ~]# cat add.txt
ybc
[root@zycentos7 ~]# cat test002.txt
i love you
but do you love me
[root@zycentos7 ~]# cat test003.txt
i love you
i love you
i love you
i love you
  1. 将test002.txt的每行后增加一行文本add 行后追加(a)
[root@zycentos7 ~]# sed 'a add' test002.txt
i love you
add
but do you love me
add
  1. sed在hosts追加 行后追加(a)
[root@zycentos7 etc]# sed -i '$a192.168.42.128controller \
> 192.168.42.102 computer' /etc/osts
[root@zycentos7 etc]# tail -1 /etc/hosts
192.168.42.102 computer
  1. 将test003.txt的第2行到第4行前增加一行文本,文本内容为ybc 行前插入(i)
[root@zycentos7 ~]# sed '2,3i ybc' test003.txt
i love you
ybc
i love you
ybc
i love you
i love you
  1. 用sed将网卡配置文件中的网关修改 替换行(c)
[root@zycentos7 ~]# sed -n '/^GATEWAY/cGATEWAY=192.168.232.111' /etc/sysconfig/network-scriptsifcfg-ens33
GATEWAY=192.168.232.111
  1. 将test003.txt的第2~3行后增加一行文本,文本内容从add.txt读入 文件合并(r)
[root@zycentos7 ~]# sed '2,3 r add.txt' test003.txt
i love you
i love you
ybc
i love you
ybc
i love you

地址界定,编辑命令

s/// 查找替换 其分隔符可自行指定,常用的有s@@@, s###等

替换标记

g 全局替换
i  不区分大小写
w file 将替换成功的结果保存至指定文件中
p 显示替换成功的行
e 执行命令标志excuate

准备文件

[root@zycentos7 ~]# cat test
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager

示例1 将test的3~5行保存到文件/root/aaa.txt中

[root@zycentos7 ~]# sed -n '3,5 w /root/aaa.txt' test

示例2 将每行的第二个a替换为A,并写入到文件out.txt

[root@zycentos7 ~]# sed -n 's/a/A/2 w out.txt' test
[root@zycentos7 ~]# cat out.txt
102,Jason Smith,IT MAnager
103,Raj Reddy,SysAdmin
104,Anand RAm,Developer
105,Jane Miller,SAles Manager

示例3 将含有Sales行的第一个Manager替换为Director

[root@zycentos7 ~]# sed '/Sales/s/Manager/Director/' test
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Director

示例4 不区分大小写,将全文的j替换为[ybc] 不区分大小写i,全局替换g

[root@zycentos7 ~]# sed 's/[jJ]/[ybc]/g' test
101,[ybc]ohn Doe,CEO
102,[ybc]ason Smith,IT Manager Manager
103,Ra[ybc] Reddy,Sysadmin
104,Anand Ram,Developer
105,[ybc]ane Miller,Sales Manager

示例5 给雇员ID(即第一列的3个数字)加上[ ],如101改成[101]

[root@zycentos7 ~]# sed 's/^[0-9][0-9][0-9]/[&]/g' test
[101],John Doe,CEO
[102],Jason Smith,IT Manager Manager
[103],Raj Reddy,Sysadmin
[104],Anand Ram,Developer
[105],Jane Miller,Sales Manager

&的作用----获取匹配到的模式:当在replacement-string中使用&时,它会被替换成匹配到的original-string或正则表达式

[root@zycentos7 ~]# sed 's/^.*/<&>/' test
<101,John Doe,CEO>
<102,Jason Smith,IT Manager Manager>
<103,Raj Reddy,Sysadmin>
<104,Anand Ram,Developer>
<105,Jane Miller,Sales Manager>

示例6 在files.txt文件中的每行前面添加ls -l 并把结果作为命令执行

[root@zycentos7 ~]# cat files.txt
/etc/passwd
/etc/group
[root@zycentos7 ~]# sed 's/^/ls -l /' files.txt
ls -l /etc/passwd
ls -l /etc/group
[root@zycentos7 ~]# sed 's/^/ls -l /e' files.txt
-rw-r--r--. 1 root root 1167 Nov 23 21:19 /etc/passwd
-rw-r--r--. 1 root root 542 Nov 23 21:19 /etc/group

高级编辑命令

h 模式空间—[覆盖]—>保持空间
H 模式空间—[追加]—>保持空间
g 保持空间—[覆盖]—>模式空间
G 保持空间—[追加]—>模式空间
x 把模式空间中的内容与保持空间中的内容互换
n 覆盖读取匹配到的行的下一行至模式空间中
N 追加读取匹配到的行的下一行至模式空间中
d 删除模式空间中的行
D 删除多行模式空间中的所有行

示例1 把第1-3行复制到文件末尾

[root@zycentos7 ~]# sed '1,3H;$G' test
101,John Doe,CEO
102,Jason Smith,IT Manager Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager

101,John Doe,CEO
102,Jason Smith,IT Manager Manager
103,Raj Reddy,Sysadmin

出现空行的原因是保持空间内默认已有一个空行
避免出现空行 sed '1h;2,3H;$G' test

把第2行复制到第4行后(不要空行)

[root@zycentos7 ~]# sed '2h;4G' test
101,John Doe,CEO
102,Jason Smith,IT Manager Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
102,Jason Smith,IT Manager Manager
105,Jane Miller,Sales Manager

示例2 显示偶数行

[root@zycentos7 ~]# sed -n 'n;p' /etc/passwd
[root@zycentos7 ~]# sed -n '2~2 p' /etc/passwd
[root@zycentos7 ~]# sed -n '2~2 =' /etc/passwd	;打印行号
命令 含义
sed '1!G;h;$!d' file 逆序显示
sed '$!d' file 取最后一行
sed '$!N;$!D' file 取最后2行
sed '/^$/d;G' file 删除原有的所有空白行,而后为所有的非空白行后添加一个空白行
sed 'n;d' file 显示奇数行
sed 'G' file 在原有的每行后方添加一个空白行

练习

准备测试文件

[root@zycentos7 ~]# cat sed.txt
northwest NW Charles Main 4.0 .99 3 35
western WE Sharon Gray 8.3 .97 5 23
southwest SW Lewis Dalsass 4.7 .8 2 19
southern SO Suan Chin 5.1 .96 4 15
southeast SE Patricia Hemenway 4.0 .7 4 16
eastern EA TB Savage 7.7 .84 5 22
northeast NE AM Main Jr. 5.1 .96 3 13
north NO Margot Weber 3.4 .87 5 8
central CT Ann Stephens 2.7 .94 5 14

练习1 默认情况下, sed 把所有输入行都打印在标准输出上,如果在某一行匹配到 north,sed就把该行另外打印一遍
加-n选项,只打印处理过的

[root@zycentos7 ~]# sed -n '/north/p' sed.txt
northwest NW Charles Main 4.0 .99 3 35
northeast NE AM Main Jr. 5.1 .96 3 13
north NO Margot Weber 3.4 .87 5 8

练习2 删除从第三行到最后一行内容,剩余各行被打印

[root@zycentos7 ~]# sed '3,$d' sed.txt
northwest NW Charles Main 4.0 .99 3 35
western WE Sharon Gray 8.3 .97 5 23

删除匹配到的行

[root@zycentos7 ~]# sed '/north/d' sed.txt
western WE Sharon Gray 8.3 .97 5 23
southwest SW Lewis Dalsass 4.7 .8 2 19
southern SO Suan Chin 5.1 .96 4 15
southeast SE Patricia Hemenway 4.0 .7 4 16
eastern EA TB Savage 7.7 .84 5 22
central CT Ann Stephens 2.7 .94 5 14

练习3 将行首的west替换成north并打印被替换过的行

[root@zycentos7 ~]# sed -n 's/^west/north/p' sed.txt
northern WE Sharon Gray 8.3 .97 5 23

将全文的west替换成north

[root@zycentos7 ~]# sed 's/south/north/g' sed.txt

练习4 在末尾是2位数的行末尾加上ybc

[root@zycentos7 ~]# sed 's/[0-9]\{2\}$/&ybc/' sed.txt
northwest NW Charles Main 4.0 .99 3 35ybc
western WE Sharon Gray 8.3 .97 5 23ybc
southwest SW Lewis Dalsass 4.7 .8 2 19ybc
southern SO Suan Chin 5.1 .96 4 15ybc
southeast SE Patricia Hemenway 4.0 .7 4 16ybc
eastern EA TB Savage 7.7 .84 5 22ybc
northeast NE AM Main Jr. 5.1 .96 3 13ybc
north NO Margot Weber 3.4 .87 5 8
central CT Ann Stephens 2.7 .94 5 14ybc

当“与”符号( &)用在替换串中时,它代表在查找串中匹配到的内容时

练习5 将文本中的Margot替换为Marlet

[root@zycentos7 ~]# sed -n '/Margot/p' sed.txt
north NO Margot Weber 3.4 .87 5 8
[root@zycentos7 ~]# sed -n 's/\(Mar\)go\(t\)/\1le\2/p' sed.txt
north NO Marlet Weber 3.4 .87 5 8

sed -n 's/\(Mar\)go\(t\)/\1le\2/p' sed.txt 包含在第一个圆括号里的模式Mar作为标签1保存在特定的寄存器中,第二个圆括号里的模式t作为标签2保存在特定的寄存器中,替换串可以通过\1 \2来引用它

练习6 将文本中的3替换为99

[root@zycentos7 ~]# sed -n 's/3/99/g' sed.txt
[root@zycentos7 ~]# sed 's#3#99#g' sed.txt
northwest NW Charles Main 4.0 .99 99 995
western WE Sharon Gray 8.99 .97 5 299
southwest SW Lewis Dalsass 4.7 .8 2 19
southern SO Suan Chin 5.1 .96 4 15
southeast SE Patricia Hemenway 4.0 .7 4 16
eastern EA TB Savage 7.7 .84 5 22
northeast NE AM Main Jr. 5.1 .96 99 199
north NO Margot Weber 99.4 .87 5 8
central CT Ann Stephens 2.7 .94 5 14

无论何字符,只要紧跟在s命令后,就是查找串替换串之间的分隔符,分隔符默认为正斜杠(可以改变,换行符、反斜线除外),此方法可以用在查找包含正斜杠的内容,例如查找路径名或生日
练习7 指定范围及替换

  1. 从含有west的行开始打印,直到遇到到含有east的行停止
[root@zycentos7 ~]# sed -n '/west/,/east/p' sed.txt
northwest NW Charles Main 4.0 .99 3 35
western WE Sharon Gray 8.3 .97 5 23
southwest SW Lewis Dalsass 4.7 .8 2 19
southern SO Suan Chin 5.1 .96 4 15
southeast SE Patricia Hemenway 4.0 .7 4 16
  1. 从第5行开始打印,直到遇到到含有northeast的行停止
[root@zycentos7 ~]# sed -n '5,/northeast/p' sed.txt
southeast SE Patricia Hemenway 4.0 .7 4 16
eastern EA TB Savage 7.7 .84 5 22
northeast NE AM Main Jr. 5.1 .96 3 13
  1. 将从含有west的行开始,到含有east的行停止,这些行的末尾添加[ybc]
[root@zycentos7 ~]# sed '/west/,/east/s/$/[ybc]/' sed.txt
northwest NW Charles Main 4.0 .99 3 35[ybc]
western WE Sharon Gray 8.3 .97 5 23[ybc]
southwest SW Lewis Dalsass 4.7 .8 2 19[ybc]
southern SO Suan Chin 5.1 .96 4 15[ybc]
southeast SE Patricia Hemenway 4.0 .7 4 16[ybc]
eastern EA TB Savage 7.7 .84 5 22
northeast NE AM Main Jr. 5.1 .96 3 13
north NO Margot Weber 3.4 .87 5 8
central CT Ann Stephens 2.7 .94 5 14

练习8 删除1~3行并将每行第一个south替换为north

[root@zycentos7 ~]# sed -e '1,3d' -e 's/south/north/' sed.txt
northern SO Suan Chin 5.1 .96 4 15
northeast SE Patricia Hemenway 4.0 .7 4 16
eastern EA TB Savage 7.7 .84 5 22
northeast NE AM Main Jr. 5.1 .96 3 13
north NO Margot Weber 3.4 .87 5 8
central CT Ann Stephens 2.7 .94 5 14

练习9 在所有含有eastern行的下一行新增Hello,world!

[root@zycentos7 ~]# sed '/eastern/a Hello,world!' sed.txt
northwest NW Charles Main 4.0 .99 3 35
western WE Sharon Gray 8.3 .97 5 23
southwest SW Lewis Dalsass 4.7 .8 2 19
southern SO Suan Chin 5.1 .96 4 15
southeast SE Patricia Hemenway 4.0 .7 4 16
eastern EA TB Savage 7.7 .84 5 22
Hello,world!
northeast NE AM Main Jr. 5.1 .96 3 13
north NO Margot Weber 3.4 .87 5 8
central CT Ann Stephens 2.7 .94 5 14

练习10 在所有含有eastern行的上一行新增Hello,world!

[root@zycentos7 ~]# sed '/eastern/i Hello,world!' sed.txt
northwest NW Charles Main 4.0 .99 3 35
western WE Sharon Gray 8.3 .97 5 23
southwest SW Lewis Dalsass 4.7 .8 2 19
southern SO Suan Chin 5.1 .96 4 15
southeast SE Patricia Hemenway 4.0 .7 4 16
Hello,world!
eastern EA TB Savage 7.7 .84 5 22
northeast NE AM Main Jr. 5.1 .96 3 13
north NO Margot Weber 3.4 .87 5 8
central CT Ann Stephens 2.7 .94 5 14

练习11 将所有含有eastern的行替换为Hello,world!

[root@zycentos7 ~]# sed '/eastern/c Hello,world!' sed.txt
northwest NW Charles Main 4.0 .99 3 35
western WE Sharon Gray 8.3 .97 5 23
southwest SW Lewis Dalsass 4.7 .8 2 19
southern SO Suan Chin 5.1 .96 4 15
southeast SE Patricia Hemenway 4.0 .7 4 16
Hello,world!
northeast NE AM Main Jr. 5.1 .96 3 13
north NO Margot Weber 3.4 .87 5 8
central CT Ann Stephens 2.7 .94 5 14

练习13 取出偶数行的用户名

[root@zycentos7 ~]# sed -nr '2~2 s/([^:]+).*/\1/gp' /etc/passwd
bin
adm
sync
halt
operator
ftp
systemd-network
polkitd
postfix
zhaoya
nginx
zhao
tcpdump

匹配非 : 至少一次(遇见:停止匹配)

练习14 将test.txt中所有的回车替换成空格

[root@zycentos7 ~]# echo "a,b,c,d"
a,b,c,d
[root@zycentos7 ~]# echo "a,b,c,d"|sed 's/,/\n/g'
a
b
c
d
[root@zycentos7 ~]# echo "a,b,c,d"|sed 's/,/\n/g'|sed 's/\n/,/g'
a
b
c
d

sed命令在处理换行符时特殊,这跟sed的行处理方式有关,sed读取一行时,会先把换行符去掉处理完后再添加上,无法使用上面的命令进行换行符替换

[root@zycentos7 ~]# echo "a,b,c,d"|sed 's/,/\n/g'|tr -t '\n' ','
a,b,c,d,[root@zycentos7 ~]#

:label; 实现跳转处理的标签 标签名label可以随便取,b/t label为跳转指令
N; 追加文本流中的下一行到模式空间进行合并处理,使换行符可见
s/\n/,/ sed的替换命令,将换行符替换为,
标签跳转和N的追加命令实现了每一行不间断放入模式处理空间,从而不会漏掉每一个换行符,而没有标签的话跳转的话,就只能每两行替换掉一个换行符

[root@zycentos7 ~]# echo "a,b,c,d" |sed 's/,/\n/g' |sed ':label;N;s/\n/,/;b label'
a,b,c,d
[root@zycentos7 ~]# echo "a,b,c,d" |sed 's/,/\n/g' |sed 'N;s/\n/,/'
a,b
c,d

练习15 找出ifconfig命令结果中的IP地址

[root@zycentos7 ~]# ifconfig ens33|sed -rn '2s/.*inet (.*)netmask.*/\1/p' 
192.168.232.125

awk

基本语法

awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
awk [options] ‘BEGIN{ action;} pattern{ action;} END{action;}file

基本格式

awk [options] ‘program’ file…
program:pattern{action statements;..}

awk 程序通常由以下3部分组成

BEGIN 语句块
BODY 能够使用模式匹配的通用语句块
END 语句块
  1. pattern和action

pattern部分决定动作语句何时触发及触发事件,也可以用正则表达式匹配,但要用扩展正则表达式,例如:BEGIN,END,/pattern/
action statements对数据进行处理,放在{}内指明,例如:print, printf

  1. program要放在单引号里,放在双引号里默认打印全部

  2. 分割符、域和记录

(1) awk执行时, 由分隔符分隔的字段(域)标记$1,$2…$n称为域标识,$0为所有域
(2)文件的每一行称为记录
(3) 省略action,则默认执行 print $0 的操作

选项

-F 指明输入时用到的字段分隔符 默认的分隔符是空格
-v var=value 自定义变量

示例1
显示含root行的用户名

[root@zycentos7 ~]# grep "root" /etc/passwd|egrep -o "^[^:]+"
[root@zycentos7 ~]# sed -rn '/root/ s/([^:]+).*/\1/pg' /etc/passwd
[root@zycentos7 ~]# awk -F: '/root/ {print $1}' /etc/passwd
root
operator

格式化输出用户名和用户UID

[root@zycentos7 ~]# awk -F: '/^root|sync/ {print $1" "$3}' /etc/passwd
root 0
sync 5
[root@zycentos7 ~]# awk -F: '/^root|sync/ {print $1,$3}' /etc/passwd
root 0
sync 5
[root@zycentos7 ~]# awk -F: 'BEGIN {print "user_name   shell_type\n------------------------"}/root/ {print $1," ",$7} END{print "------------------------"}' /etc/passwd
user_name   shell_type
------------------------
root   /bin/bash
operator   /sbin/nologin
------------------------

显示用户UID大于500的用户名

[root@zycentos7 ~]# awk -F: '$3>500 {print $1}' /etc/passwd
polkitd
zhaoya
saslauth
nginx
test1
zhao
nologin
bash

自定义分隔符 FS(默认为空格)

[root@zycentos7 ~]# awk 'BEGIN{FS=":"}{print $1}' test

格式化输出

[root@zycentos7 ~]# awk -F: '{printf "%-15s %10d\n",$1,$3}' /etc/passwd
[root@zycentos7 ~]# awk -F: '{printf "username: %s,UID: %d\n",$1,$3}' /etc/passwd

内置变量

内置变量 描述
FS 输入字段分隔符,默认情况下为一个空格
OFS 输出字段分隔符
RS 输入记录分隔符,默认情况下为一个换行符
ORS 输出记录分隔符
NF 域的数量($NF指最后一个域,$(NF-1)指倒数第二个域)
NR 行数
FNR 分别计算行数
FILENAME 当前输入文件的名称
ARGC 命令行参数个数(ARGC-1判断awk读入文件的个数)
ARGV 命令行参数排列
[root@zycentos7 ~]# awk -v FS=":" -v OFS=":" '{print $1,$3,$7}' /etc/passwd
[root@zycentos7 ~]# awk '{print $0}' a
a b c d e f
[root@zycentos7 ~]# awk -v RS=" " '{print $0}' a
a
b
c
d
e
f

自定义变量

[root@zycentos7 ~]# awk -F: -v test="ybc" '{print test}' /etc/passwd
[root@zycentos7 ~]# awk -F: 'BEGIN {test="username:"} {print test,$1}' /etc/passwd

打印所有可登录shell的用户的数目

[root@zycentos7 ~]# awk -F: '$NF ~ /\/bin\/bash/ {n++};END{print n}' /etc/passwd
5

数组

按索引取值

[root@zycentos7 ~]# awk -F: '{username[i++]=$1}END{for(k=0;k<i;k++){print username[k]}}' passwd

按内容取值(随机输出,不按顺序)

[root@zycentos7 ~]# awk -F: '{username[i++]=$1}END{for(i in username){print i,username[i]}}' passwd

示例1 统计/etc/passwd 中各种类型shell的数量

[root@zycentos7 ~]# awk -F: '{shells[$NF]++}END{for(i in shells) {print i,shells[i]}}' passwd
/bin/sync 1
/bin/bash 5
/bash/nologin 1
/sbin/nologin 19
/sbin/halt 1
/sbin/shutdown 1

正常逻辑:awk -F: '{shells[i++]=$NF}END{for(i in shells) {print i,shells[i]}}' passwd
本题解题思路:将索引与值交换位置,shells[$NF]的值默认为0,读取记录,相同类型的shell不再重新开辟空间(索引不能重复),直接给相应索引的值加1

示例2 网站访问状态统计<当前时实状态 netstat>

[root@zycentos7 ~]# netstat -ant|grep :80 |awk '{access_stat[$NF]++} END{for (i in access_stat){print i,access_stat[i]}}'
LISTEN 1

TIME_WAIT数值过高,处于半连接状态的连接太多,SYNFLOOD

示例3 统计当前访问的每个IP的数量<当前时实状态 netstat,ss>

示例4 统计Apache/Nginx日志中某一天的PV量<统计日志>

[root@zycentos7 ~]# awk '{access_ip[$1]++}END{for(i in access_ip){print i,access_ip[i]}}' /var/log/httpd/access_log

日访问量大于500的客户重点关注 awk '{access_ip[$1]++}END{for(i in access_ip){if(access_ip[i]>500){print i,access_ip[i]}}}' /var/log/httpd/access_log

示例5 统计Apache/Nginx日志中某一天不同IP的访问量<统计日志><统计日志>
示例6 统计/etc/passwd 中各种类型shell的数量

发布了43 篇原创文章 · 获赞 30 · 访问量 5942

猜你喜欢

转载自blog.csdn.net/qq_42049496/article/details/102459070