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

正则表达式

grep 正则表达式引擎

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

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

命令语法

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

OPTION

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

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

-q 静默模式,不输出任何信息
- - color=auto 匹配到的文本着色后高亮显示
-P --perl-regexp 使用perl的正则表达式语法
ifconfig eth2|grep -Po ‘(?<=addr:).*(?= Bcast)’

1.egrep==grep -E,使用扩展的正则表达式对文本进行搜索
2.fgrep==grep -F,利用固定的字符串来对文本进行搜索(不支持正则表达式&&执行速度最快)

练习

练习1 匹配/etc/passwd中含有operator的及其前后各3行
grep -C 3 "operator" /etc/passwd
练习2 找出ifconfig命令结果中的IP地址
ifconfig | grep -Eo "(\<[0-9]{1,3}\>\.){3}\<[0-9]{1,3}\>" | head -n 1
只匹配合法IP
ifconfig |grep -Eo "(\<(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\>\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
练习3 匹配邮箱
egrep '[[:alnum:]]+@[[:alnum:]]+\.[a-z]+' c
练习4 显示当前系统上root、centos或user1用户的默认的shell和UID
grep "bash$" /etc/passwd|sort -n -t: -k 3|head -1|cut -d: -f1
练习5 找出/etc/passwd文件中的两位数或三位数
egrep '\<[0-9]{2,3}\>' /etc/passwd
练习6 找出/etc/rc.d/rc.sysinit或/etc/grub2.cfg文件中,以至少一个空白字符开头,且后面非空白字符的行
grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg
练习7 找出"netstat -tan"命令的结果中以’LISTEN’后跟0、1或多个空白字符结尾的行
netstat -tan | grep "LISTEN[[:space:]]*$"
练习8 找出/proc/meminfo文件中以大写或小写S开头的行
grep -E "^(s|S)" /proc/meminfo
练习9 找出/etc/rc.d/init.d/functions文件中的函数(某单词后面跟一个小括号的行)
grep -o "[_[:alnum:]]*()" /etc/rc.d/init.d/functions
练习10 使用echo命令输出一绝对路径,使用egrep取出基名
echo /etc/sysconfig | grep -E -o "[^/]+/?$"
练习11 找出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])\>"
练习12 找出/etc/passwd文件中用户名同shell名的行
grep -E "^([^:]+\>).*\1$" /etc/passwd
练习13 找出ifcfg-ens33文件中的所有合法IP
egrep '([0-9]{1,3}\.){3}[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-ens33


sed

工作原理

名词 解释
模式空间 pattern space 模式空间在内存中处理文件的每个输入行
保持空间 holding space 保持空间在内存中保存已经处理过的输入行
非交互式 在命令行下输入编辑命令,在屏幕上查看输出
流式 每次读入一行处理并在屏幕上输出结果

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

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

Linux基础篇学习——文件搜索工具grep,sed,awk_第1张图片

命令语法

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

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

OPTION

-n 不输出模式空间中的内容到屏幕 默认情况下,sed 把所有输入行都打印在标准输出上,如果在某一行匹配到north,sed就把该行另外打印一遍,加-n选项,只打印处理过的
-r支持扩展正则表达式
-e script 多点编辑
-f file 每行编辑一个命令
-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

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

[root@zycentos7 ~]# cat test-script.sed
/^root/ p
/^adm/ p
[root@zycentos7 ~]# sed -nr -f test-script.sed /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
分步操作如下:
[root@zycentos7 ~]# sed -n '{
> /^root/ p
> /^adm/ p
> }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin

地址界定

(1) 空地址
对全文进行处理
(2) 单地址

格式 含义
# 指定行
^ 行首
$ 行尾
/pattern/ 被此模式所匹配到的每一行 /为边界符号可更改
/pattern/I 匹配时忽略大小写 大写的i

(3) 地址范围
#,#3,5 3-5行
#,+#3,+5 3-8行
#,/pat1/ 从#行开始到第一次能够被匹配到的行
/pat1/,/pat2/ 被模式匹配到的行内的所有的行
(4) 步进:~
1~2 所有奇数行
2~2 所有偶数行
1~1 所有行
n~n 所有n的倍数行(n不等于1)

示例二

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

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

编辑命令

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

示例三

示例4 sed删除的应用

101,John Doe,CEO

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

104,Anand Ram,Developer
105,Jane Miller,Sales Manager
# 106,Ian Yi,Actor
 #107,Evan Ma,Actor
  1. 删除空行 sed '/^$/ d' test
  2. 删除开头第一个字符是 # 的行(删除注释行) sed '/^#/ d' test
  3. 删除行首的#号 sed -n 's/^#//gp' test
  4. 删除以#开头,且后面跟了至少一个空白字符的行的#和空白字符 sed -nr 's/^#[[:space:]]+//gp' test
  5. 删除以空白字符后面跟#的行中的开头的空白字符及# sed -nr 's/^[[:space:]]+#+//gp' test

示例5 行后追加(a)、行前插入(i)、替换行(c)、文件合并(r)、文件导出(w)

  1. sed在hosts追加 行后追加(a)
[root@zycentos7 ~]# sed -i '$ a 192.168.42.102 computer' /etc/hosts
[root@zycentos7 ~]# tail -1 /etc/hosts
192.168.42.102 computer
  1. 将/etc/passwd的第2行到第4行前增加一行文本,文本内容为ybc 行前插入(i) sed '2,3i ybc' /etc/passwd
  2. 用sed将网卡配置文件中的网关修改 替换行(c)
[root@zycentos7 ~]# sed -n '/^GATEWAY/ c GATEWAY=192.168.232.111' /etc/sysconfig/network-scriptsifcfg-ens33
GATEWAY=192.168.232.111
  1. 在/etc/passwd第2行和第4行后读入文件newfile 文件合并(r) sed -e '1 r newfile' -e '5 r newfile' /etc/passwd
  2. 把指定的行root写入到一个文件newfile中 文件导出(w) sed -n '/^\/ w newfile' /etc/passwd

地址界定,编辑命令

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

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

替换标记

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

示例四

示例6 替换标记加g不加g的区别实例

hello hello hello  
  hello  hello
hello  hello hello
[root@localhost ~]# sed 's/hello/nihao/' a
nihao hello
  nihao  hello
nihao  hello hello
[root@localhost ~]# sed 's/hello/nihao/g' a
nihao nihao
  nihao  nihao
nihao  nihao nihao

s///g:匹配每一行由行首到行尾的所有字符
s///:匹配每一行的行首开始匹配,匹配到第一个符合的字段,就会结束,跳到下一行

[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 Manager

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

[root@zycentos7 ~]# sed -n 's/a/A/2 w out.txt' test

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

[root@zycentos7 ~]# sed -n '/Sales/ s/Manager/Director/ p' test
105,Jane Miller,Sales Director

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

[root@zycentos7 ~]# sed -n 's/j/[ybc]/ig p' test
101,[ybc]ohn Doe,CEO
102,[ybc]ason Smith,IT Manager Manager
103,Ra[ybc] Reddy,Sysadmin
105,[ybc]ane Miller,Sales Manager

示例10 &在sed替换中的应用
给雇员ID(即第一列的3个数字)加上[ ],如101改成[101]

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

(1) 在末尾是2位数的行末尾加上ybc sed 's/[0-9]\{2\}$/&ybc/' filename
(2) 在/etc/passwd的20行到末行最前面加’aaa:’ sed '20,$ s/^.*$/aaa:&/g' /etc/passwd

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

高级编辑命令

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
(8888888) 
(12231)

练习1 sed替换分组引用实例

  1. 将文本中的Margot替换为Marlet sed -nr 's/(Mar)go(t)/\1le\2/g p' sed.txt

包含在第一个圆括号里的模式Mar作为标签1保存在特定的寄存器中,第二个圆括号里的模式t作为标签2保存在特定的寄存器中,替换串可以通过\1 \2来引用它

  1. 替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5 sed -nr 's/(id:)3(:initdefault:)/\15\2/p' /etc/inittab
  2. 去掉括号 sed -nr 's/\((.*)\)/\1/gp' file

练习2 指定范围及替换

  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. 删除1~3行,并将每行第一个south替换为north
[root@zycentos7 ~]# sed -e '1,3 d' c -n -e 's/south/north/ p' sed.txt
northern SO Suan Chin 5.1 .96 4 15
northeast SE Patricia Hemenway 4.0 .7 4 16
northwest SW Lewis Dalsass 4.7 .8 2 19
northern SO Suan Chin 5.1 .96 4 15
northeast SE Patricia Hemenway 4.0 .7 4 16
  1. 在所有含有eastern行的下一行新增Hello,world!
[root@zycentos7 ~]# sed '/eastern/a Hello,world!' sed.txt

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

[root@zycentos7 ~]# sed -nr '2~2 s/([^:]+).*/\1/gp' /etc/passwd

匹配非 : 至少一次(遇见:停止匹配)
练习4 将test.txt中所有的逗号替换成空格

a,b,c,d
[root@zycentos7 ~]# sed 's/,/\n/g' test.txt
a
b
c
d
[root@zycentos7 ~]# sed 's/,/\n/g' test.txt|sed 's/\n/,/g'	;无法替换
a
b
c
d

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

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

练习5 label跳转标签
: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

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

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

练习7 取路径目录及文件名称
取出一个文件路径的目录名称 sed -nr 's/(.*)\/.+/\1/gp' file
取出一个文件路径的文件名称 sed -nr 's/.*\/(.+)/\1/gp' file
练习8 精确匹配

  1. 在/etc/fstab文件中不以#开头的行的行首增加#号 sed -n 's/^[^#]/#/gp' /etc/fstab
  2. 只查看包含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:后必须有信息

练习9 在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

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 自定义变量

内置变量

内置变量 描述
FS 输入字段分隔符,默认情况下为一个空格
OFS 输出字段分隔符
RS 输入记录分隔符,默认情况下为一个换行符
ORS 输出记录分隔符
NF 域的数量($NF指最后一个域,$(NF-1)指倒数第二个域)
NR 行数
FNR 分别计算行数
FILENAME 当前输入文件的名称
ARGC 命令行参数个数(ARGC-1判断awk读入文件的个数)
ARGV 命令行参数排列
  1. 对/etc/passwd文件中输出的每一行计数 NR
awk '{print NR,$0}' /etc/passwd
  1. 对/etc/passwd、/etc/fstab文件中输出的每一行分别计数 FNR
awk '{print FNR,$0}' /etc/passwd /etc/fstab
  1. 自定义变量 -v
awk -v test="ybc" 'BEGIN{print test}'
awk -F: 'BEGIN {test="username:"} {print test,$1}' /etc/passwd
awk -v FS=":" -v OFS=":" '{print $1,$3,$7}' /etc/passwd
awk -v RS=" " '{print $0}' file
  1. 打印所有可登录shell的用户的数目 NF
awk -F: '$NF ~ /\/bin\/bash/{n++};END{print n}' /etc/passwd
  1. 分别用sed,grep,awk给文件增加行号
sed = /etc/passwd |sed 'N;s/\n/\t/'
grep -n "" /etc/passwd
awk '{print NR" "$0}' /etc/passwd

数组

按索引取值

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

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

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

awk之文本替换

awk的sub/gsub函数用来替换字符串,sub函数在第一次匹配时进行替换,gsub函数在整个文档中进行替换

sub(/regexp/, replacement)	;在整个记录中匹配
sub(/regexp/, replacement, target)	;在整个记录的第一个域中进行匹配
target默认使用$0作为参数

file文本准备

yyyybc is a actor,yes actor
ian is also a actor,yes aactor
yybc is a aactor,actor
ian is a boy,ian
ybc is a boy,too

示例1 替换单个串
把每行的第一个actor替换为star

awk '{sub(/actor/,"star"); print}' file

示例2 替换换所有的串
把全文的actor替换为star

awk '{gsub(/actor/,"star"); print}' file

示例3 替换满足条件的行的串
将出现字符串ian行的actor替换为star

awk '/ian/ {gsub(/actor/,"star"); print}' file

示例4 替换多个字符串
把全文的ybc、ian替换为star

awk '{gsub(/ybc|ian/,"star"); print}' file

示例5 严格匹配单词
将出现的单词actor替换为star

awk '{ sub(/\/,"star"); print}' t.txt

示例6 匹配规则表达式
将行首的y无论连续几个都替换成字符s

awk '{ gsub(/^y*/,"s"); print}' t.txt

练习

一、有关/etc/passwd的实例

1./etc/passwd 中匹配包含root或net或ucp的任意行
awk -F: '/root|net|ucp/ {print}' /etc/passwd
2. 统计当前系统上UID大于500的用户的个数 逻辑判断、自定义变量
awk -F: -v sum=0 '{if($3>500)sum++}END{print sum}' /etc/passwd
awk -F: '$3>500{n++};END{print n}' /etc/passwd
3. 对/etc/passwd、/etc/fstab文件中输出的每一行分别计数 内置变量FNR
awk '{print FNR,$0}' /etc/passwd /etc/fstab
4. 以printf格式输出用户名,UID、GID 格式化输出
awk -F: '{printf "%-15s %d %8i\n",$1,$3,$4}' /etc/passwd
5. 格式化输出root和sync用户的用户名和登录shell 格式化输出、程序块实例

awk -F: 'BEGIN {print "user_name   shell_type\n------------------------"}/^root|sync/ {print $1," ",$7} END{print "------------------------"}' /etc/passwd
输出如下:
user_name   shell_type
------------------------
root   /bin/bash
sync   /bin/sync
------------------------
  1. 检测当前系统上所有用户,如果用户名为root输出:Admin,如果用户名不为root输出:Common User
    awk -F: '{if($1=="root")printf "%-15s:%s\n",$1,"Admin";else printf "%-15s:%s\n",$1,"Common User"}' /etc/passwd

print与printf的区别:
(1) print 中不能使用%s ,%d 或%c
(2) print 自动换行,printf 没有自动换行

  1. 读取/etc/passwd文件中的每一行的每一个字段,输出每个字段中字符个数大于等于四的字段
    awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd
  2. 分别使用do-while和for语句输出/etc/passwd中每一行中的前三个字段
    awk -F: '{i=1;do{print $i;i++}while(i<=3)}' /etc/passwd
    awk -F: '{for(i=1;i<=3;i++)print $i}' /etc/passwd
  3. 显示当前系统上UID号为偶数的用户名和UID
    awk -F: '{if($3%2!=1){printf "%-15s%d\n",$1,$3}}' /etc/passwd
  4. 输出/etc/passwd中的每一行以||||隔开,默认不换行
    awk -F: 'BEGIN{ORS="||||"}{print $0}' /etc/passwd
  5. 打印行号小于15的,并且最后一域匹配bash的信息
    awk -F: '{if($NR<15 && $NF~/bash/)print $0}' /etc/passwd
  6. 请打印出第三域数字之和
    awk -F: '{sum+=$3}END{print sum}' /etc/passwd
  7. 显示含root行的用户名
grep "root" /etc/passwd|egrep -o "^[^:]+"
sed -rn '/root/ s/([^:]+).*/\1/pg' /etc/passwd
awk -F: '/root/ {print $1}' /etc/passwd
  1. 统计/etc/passwd 中各种类型shell的数量
[root@zycentos7 ~]# awk -F: '{shells[$NF]++}END{for(i in shells) {print i,shells[i]}}' /etc/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

二、命令灵活运用练习
  1. 获得内存使用情况
    free -m|awk 'NR==2{print $3*100%/$2}'
  2. 获得磁盘使用情况
    df|awk '/\/$/{print $5}'
  3. 清空本机的ARP缓存 xargs待学习
    arp -n |awk '/^[0-9]/{print $1}' |xargs -I {} arp -d {}
  4. 打印出/etc/hosts文件的最后一个字段(按空格分隔)
    awk '{print $NF}' /etc/hosts
  5. 打印指定目录下的目录名
    find /home -type d|awk -F"/" '{print $NF}'
  6. 获取根分区剩余大小
    df -h|awk '/\/$/{print $(NF-1)}'
  7. 获取当前机器ip地址
    ifconfig ens33|grep "\"|awk '{print $2}'
  8. 取得网卡IP(除ipv6以外的所有IP)
    ifconfig |awk '/[ ]inet[ ]/{print $2}'
三、关于网络运行状态的监控统计练习
ps -aux|grep nginx
systemctl stop firewalld
setenforce 0
kill -9 PID ;终止占用80端口的进程
【nginx】
yum install nginx -y
cd /usr/share/nginx	;配置目录
cd /var/log/nginx/access.log	;日志文件
【apache】
yum install httpd -y
vim /etc/httpd/conf/httpd.conf	;配置文件
	#ServerName www.example.com:80   ;把#去掉【解决未设定ServerName】
cd /var/log/httpd/access_log	;日志文件
  1. 网站访问状态统计 当前时实状态netstat
    netstat -ant|tail -n +3|awk '{access_stat[$NF]++} END{for (i in access_stat){print i,access_stat[i]}}'

tail -n +k,从第k行开始
若TIME_WAIT数值过高,处于半连接状态的连接太多,SYNFLOOD

  1. 统计当前访问的每个IP的数量 当前时实状态netstat,ss
    ss ss -an|grep :22|awk -F":" '/ESTAB/{ip_count[$(NF-1)]++} END{for(i in ip_count){print i,ip_count[i]}}' |sort -k2 -rn|awk '{print $2,$3}'
    netstat netstat -ant|grep :22|awk -F: '/ESTAB/{ip_count[$(NF-1)]++}END{for(i in ip_count){print i,ip_count[i]}}'
  2. 统计Apache/Nginx日志中某一天的PV量 统计日志
    awk '{access_ip[$1]++}END{for(i in access_ip){print i,access_ip[i]}}' access_file

PV(Page View),访问量,即页面浏览量或者点击量,用户每次对网站的访问均被记录1次,用户对同一页面的多次访问,访问量值累计

  1. 统计Apache/Nginx日志中某一天不同IP的访问量 统计日志
    grep '23/Jan/2020' access_file |awk '{ips[$1]++} END{for(i in ips){print i,ips[i]} }' |sort -k2 -rn
  2. 查看TCP连接状态
    netstat -nat|tail -n +3|awk '{print $6}'|sort|uniq -c
  3. 查找请求连接前20个IP(常用于查找攻击源)
    netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n 20
  4. 用tcpdump嗅探80端口的访问看看谁最高
    tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -20
  5. 获取Apache访问前10位的ip地址
    awk '{print $1}' access.log|sort|uniq -c|sort -nr|head -10
  6. 统计Apache404的连接
    awk '$9 ~/404/ {print $9,$7}' access.log|sort
  7. 统计当前系统上以tcp协议工作的各端口的状态数
    netstat -ant | awk '/^tcp/ {++STATE[$NF]} END {for(i in STATE) print i, STATE[i]}'
  8. 日访问量大于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
四、综合练习
姓名:电话:过去三个月里的捐款
Mike Harrington:[510] 548-1278:250:100:175
Christian Dobbins:[408] 538-2358:155:90:201
Susan Dalsass:[206] 654-6279:250:60:50
Archie McNichol:[206] 548-1348:250:100:175
Jody Savage:[206] 548-1278:15:188:150
Guy Quigley:[916] 343-6410:250:100:175
Dan Savage:[406] 298-7744:450:300:275
Nancy McNeil:[206] 548-1278:250:80:75
John Goldenrod:[916] 348-4278:250:100:175
Chet Main:[510] 548-5258:50:95:135
Tom Savage:[408] 926-3456:250:168:200
Elizabeth Stachelin:[916] 440-1763:175:75:300
  1. 显示所有以一个C或E开头的名
    awk -F: '{print $1}' file|awk '$1~/\<[CE]/ {print $1}'
  2. 显示所有只有四个字符的名
    awk -F: '{print $1}' file|awk 'length($1)=="4" {print $1}'
    length函数,举例: length($1)==10 $1字符为10
  3. 显示Mike的捐款.显示每个值时都有以$开头
    awk -F: '/^Mike/ {print"$"$3"$"$4"$"$5}' file

你可能感兴趣的:(Linux基础,Linux基础篇学习,文件搜索工具,grep,正则表达式,egrep)