02-三剑客命令grep、sed、awk

1. grep命令

作用:作用是在文件中提取和匹配符合条件的字符串

[root@localhost ~]# grep [选项] "搜索内容" 文件名

-c 计算找到‘搜索字符串’的行数
-o 指输出匹配的内容
-i 不区分大小写
-n 显示匹配内容的行号
-r 当指定要查找的是目录而非文件时,必须使用这项参数,也就是递在目录中归查找内容
-v 反向选择,即没有‘搜索字符串’内容的行
-E 扩展 grep,即 egrep,可以使用扩展正则表达式
-l 列出文件内容符合指定的范本样式的文件名称
--color=auto 搜索关键词显示颜色
-V 显示软件版本信息

案例:

# 从tesh.sh中查找包含echo行的信息
[root@localhost ~]# grep "echo" test.sh
# 从tesh.sh中查找包含echo行的信息,只统计行数
[root@localhost ~]# grep -c "echo" test.sh
5

2. Shell常见通配符

用于匹配文件名,完全匹配

通 配 符 作 用
? 匹配一个任意字符
* 匹配0个或任意多个任意字符,也就是可以匹配任何内容
[] 匹配中括号中任意一个字符。例如,[abc]代表一定匹配一个字符,或者是a,或者是b,或者是c
[-] 匹配中括号中任意一个字符,-代表一个范围。例如,[a-z]代表匹配一个小写字母
[^] 逻辑非,表示匹配不是中括号内的一个字符。例如,[^0-9]代表匹配一个不是数字的字符

练习:

[root@localhost ~]# touch abc abcd acc acd bcd bbbde 123a 234d b453 a_c  abccd
[root@localhost ~]# ls
123a  234d  abc  abcd  acc a_c acd  b453  bbbde  bcd   abccd

# 查找文件名为abc的文件,精确查找
[root@localhost ~]# find ./ -type f -name "abc"
./abc

# 查找包含文件名为abc的文件,模糊查找
[root@localhost ~]# find ./ -type f -name "abc*"
./abc
./abcd
./abccd

# 查找a和c的中间为任意一个字符的文件
[root@localhost ~]# find ./ -type f -name "a?c"
./abc
./acc
./a_c

# 查找a和c中间只能是a b _其中任意一个字符的文件
[root@localhost ~]# find ./ -type f -name "a[bc_]c"
./abc
./acc
./a_c

# 查找a和c中间只能是小写字母其中任意一个字符的文件
[root@localhost ~]# find ./ -type f -name "a[a-z]c"
./abc
./acc

# 查找cd前面是任意一个小写字母的文件
[root@localhost ~]# find ./ -type f -name "[a-z]cd"
./acd
./bcd

# 查找a和c中间不包含字母的文件
[root@localhost ~]# find ./ -type f -name "a[^a-z]c"
./a_c

3. 基础正则

用于匹配字符串,包含匹配

元字符 作 用
* 前一个字符匹配0次或任意多次。
. 匹配除了换行符外任意一个字符
^ 匹配行首。例如:^hello会匹配以hello开头的行。
$ 匹配行尾。例如:hello&会匹配以hello结尾的行
[] 匹配中括号中指定的任意一个字符,只匹配一个字符。例如:[aoeiu] 匹配任意一个元音字母,[0-9] 匹配任意一位数字, [a-z]、[0-9]匹配小写字和一位数字构成的两位字符。
[^] 匹配除中括号的字符以外的任意一个字符。例如:[^0-9] 匹配任意一位非数字字符,[^a-z] 表示任意一位非小写字母。
\ 转义符。用于取消讲特殊符号的含义取消
表示其前面的字符恰好出现n次。例如:[0-9]{4} 匹配4位数字,[1][3-8][0-9]{9} 匹配手机号码。
表示其前面的字符出现不小于n次。例如: [0-9]{2,} 表示两位及以上的数字
表示其前面的字符至少出现n次,最多出现m次。例如: [a-z]{6,8} 匹配6到8位的小写字母。

4. sed命令

字符流编辑工具(行编辑工具)==按照每行中的字符进行处理操作

命令格式: sed [选项] ‘[动作]’ 文件名

命令作用:

  1. 擅长对行进行操作处理
  2. 擅长将文件的内容信息进行修改调整/删除

具体功能作用:

  1. 文件中添加信息的能力 (增)
  2. 文件中删除信息的能力 (删)
  3. 文件中修改信息的能力 (改)
  4. 文件中查询信息的能力 (查)

选项:

选项参数 作用
-n sed命令会把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕
-e 允许对输入数据应用多条sed命令编辑
-r 在sed中支持扩展正则表达式
-i 用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出,写入磁盘

动作:

p print 输出指定的行
i insert 插入信息,在指定信息前面插入新的信息
a append 附加信息,在指定信息后面附加新的信息
d delete 删除指定信息
s substitute 替换信息 s#旧信息#新信息#g(全局替换)
c 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结。

sed命令 练习:

# 准备练习内容
[root@zabbix linux_study]#  cat  a.txt
name    age  gender  qq
pyhton  23   F       12324214214
linux   44   M       44454667
java    99   F       98989898
C       89   F       889877666
c++     78   M       8797665599

### 根据文件内容的行号进行查询
# 显示指定行号信息
[root@zabbix linux_study]# sed -n "1p" a.txt 
name    age  gender  qq

# 根据行号信息,输出多行内容(连续)
[root@zabbix linux_study]# sed -n "1,3p" a.txt 
name    age  gender  qq
pyhton  23   F       12324214214
linux   44   M       44454667

# 根据行号信息,输出多行内容(不连续)
[root@zabbix linux_study]# sed -n "1p;4p" a.txt 
name    age  gender  qq
java    99   F       98989898

### 根据文件内容的信息进行查询:
# 根据内容信息,输出单行内容
[root@zabbix linux_study]# sed -n "/linux/p" a.txt 
linux   44   M       44454667

# 根据内容信息,输出多行内容(连续)
[root@zabbix linux_study]# sed -n "/python/,/java/p" a.txt 
python  23   F       12324214214
linux   44   M       44454667
java    99   F       98989898

# 根据内容信息,输出多行内容(不连续)
[root@zabbix linux_study]# sed -n "/python/p;/java/p" a.txt 
python  23   F       12324214214
java    99   F       98989898

### sed添加信息 如果要真实修改文件内容,加上-i参数,-i和-n参不能同时使用 
# 在第二行添加[root@zabbix linux_study]# sed -r "2ic#\t99\t989988" a.txt 
name    age  gender  qq
c#	99	989988
python  23   F       12324214214
linux   44   M       44454667
java    99   F       98989898
C       89   F       889877666
c++     78   M       8797665599

# 在最后一行添加
[root@zabbix linux_study]# sed -r "\$ac#\t99\tF\t989988" a.txt 
name    age  gender  qq
python  23   F       12324214214
linux   44   M       44454667
java    99   F       98989898
C       89   F       889877666
c++     78   M       8797665599
c#	99	F	989988

# 在第二行后面添加
[root@zabbix linux_study]# sed -r "2ac#\t99\tF\t989988" a.txt 
name    age  gender  qq
python  23   F       12324214214
c#	99	F	989988
linux   44   M       44454667
java    99   F       98989898
C       89   F       889877666
c++     78   M       8797665599

### sed删除信息  如果要真是删除信息,加上-i参数
# 删除指定行信息
[root@zabbix linux_study]# sed "2d" a.txt 
name    age  gender  qq
linux   44   M       44454667
java    99   F       98989898
C       89   F       889877666
c++     78   M       8797665599

# 删除文件中第2行到第4行内容
[root@zabbix linux_study]# sed "2,4d" a.txt 
name    age  gender  qq
C       89   F       889877666
c++     78   M       8797665599

#删除文件中第2行到第4行内容
[root@zabbix linux_study]# sed "2d;4d" a.txt 
name    age  gender  qq
linux   44   M       44454667
C       89   F       889877666
c++     78   M       8797665599

#删除有linux行的信息
[root@zabbix linux_study]# sed "/linux/d" a.txt 
name    age  gender  qq
python  23   F       12324214214
java    99   F       98989898
C       89   F       889877666
c++     78   M       8797665599

### sed修改信息,把含有python的行的python改成harris
[root@zabbix linux_study]# sed "s#python#harris#g" a.txt 
name    age  gender  qq
harris  23   F       12324214214
linux   44   M       44454667
java    99   F       98989898
C       89   F       889877666
c++     78   M       8797665599

5. awk编程

printf格式化输出

[root@m01 ~]# printf '输出类型输出格式' 输出内容 

输出类型:  
    %ns:  输出字符串。n 是数字指代输出几个字符  
    %ni:  输出整数。n 是数字指代输出几个数字  
    %m.nf:输出浮点数。m 和 n 是数字,指代输出的整数位数和小数位数。				  			 如%8.2f     代表共输出 8 位数,其中 2 位是小数,6 位是整数。 
输出格式: 
    \n:   换行  
    \t:   水平输出退格键,也就是 Tab 键  
    \a:   输出警告声音  
    \b:   输出退格键,也就是 Backspace 键  
    \f:   清除屏幕  
    \r:   回车,也就是 Enter 键  
    \v:   垂直输出退格键,也就是 Tab 键 

### 格式输出
[root@m01 ~]# printf 'name\t age\t gender\n test\t 23\t 男\n'
name	age	gender
test	23	男

[root@m01 ~]# printf 'name\tage\tgender\taverage\n%s\t%2i\t%s\t%4.2f\n' test 22 F 22.12
name	age	gender	average
test	22	F	22.12

简介:擅长对列进行操作和进行数据信息的统计,AWK是一种处理文本文件的语言,是一个强大的文本分析工具

命令作用:

1. 排除信息
2. 查询信息
3. 统计信息
4. 替换信息

命令格式: awk [选项参数] '条件1{动作1} 条件2{动作2} 文件名

  • 选项参数说明:

    • -F fs or --field-separator fs
      指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
    • -v var=value or --asign var=value
      赋值一个用户定义变量。
    • -f scripfile or --file scriptfile
      从脚本文件中读取awk命令。
    • -mf nnn and -mr nnn
      对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
    • -W compact or --compat, -W traditional or --traditional
      在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
    • -W copyleft or --copyleft, -W copyright or --copyright
      打印简短的版权信息。
    • -W help or --help, -W usage or --usage
      打印全部awk选项和每个选项的简短说明。
    • -W lint or --lint
      打印不能向传统unix平台移植的结构的警告。
    • -W lint-old or --lint-old
      打印关于不能向传统unix平台移植的结构的警告。
    • -W posix
      打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符=不能代替=;fflush无效。
    • -W re-interval or --re-inerval
      允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
    • -W source program-text or --source program-text
      使用program-text作为源代码,可与-f命令混用。
    • -W version or --version
      打印bug报告信息的版本。
  • 条件

    awk保留字 BEGIN 在 awk 程序一开始时,尚未读取任何数据之前执行
    END 在 awk 程序处理完所有数据,即将结束时执行
    关系运算符 > 大于
    < 小于
    >= 大于等于
    <= 小于等于
    == 等于。用于判断两个值是否相等,如果是给变量赋值,使用 “=”号
    != 不等于
    A~B 判断字符串 A 中是否包含能匹配 B 表达式的子字符串
    A!~B 判断字符串 A 中是否不包含能匹配 B 表达式的子字符串
    正则表达式 /正则/ 在“//”中可以写入字符,也可以写正则表达式
  • 动作

    • 格式化输出
    • 流程控制语句

awk内置变量

$0 代表目前 awk 所读入的整行数据。我们已知 awk 是一行一行读入数据 的,$0 就代表当前读入行的整行数据
$n 代表目前读入行的第 n 个字段。
NR 当前 awk 所处理的行,是总数据的第几行
NF 当前行拥有的字段(列)总数, ($NF-n)表示倒数第n列
FS 用户定义分隔符。awk 的默认分隔符是任何空格,如果想要使用其他 分隔符(如“:”),就需要 FS 变量定义
ARGC 命令行参数个数
ARGV 命令行参数数组
FNR 当前文件中的当前记录数(对输入文件起始为 1)
OFMT 数值的输出格式(默认为%.6g)
OFS 输出字段的分隔符(默认为空格)
RS 输入记录分隔符(默认为换行符)
ORS 输出记录分隔符(默认为换行符)

练习

## 练习环境准备
[root@m01 ~]# cat > test.txt << EOF
> 姓       名        ID          捐款记录
> Zhang  Dandan    41117397    :250:100:175
> Zhang  Xiaoyu    390320151   :155:90:201
> Meng   Feixue    80042789    :250:60:50
> Wu     Waiwai    70271111    :250:80:75
> Liu    Bingbing  41117483    :250:100:175
> Wang   Xiaoai    3515064655  :50:95:135
> Zi     Gege      1986787350  :250:168:200
> Li     Youjiu    918391635   :175:75:300
> Lao    Nanhai    918391635   :250:100:175
> EOF

## 查询信息
    逗号,表示连续的显示一段行号开头的信息
    分号;表示指定行号显示
# NR:查询指定第几行信息 
[root@m01 ~]# awk 'NR==2' t1.txt 
Zhang  Xiaoyu    390320151   :155:90:201
# 查询第2到第4行的信息
[root@m01 ~]# awk 'NR==2,NR==4' t1.txt 
Zhang  Xiaoyu    390320151   :155:90:201
Meng   Feixue    80042789    :250:60:50
Wu     Waiwai    70271111    :250:80:75
# 查询第1行、第4行的信息
[root@m01 ~]# awk 'NR==1;NR==4' t1.txt 
Zhang  Dandan    41117397    :250:100:175
Wu     Waiwai    70271111    :250:80:75
# 使用//查询
[root@m01 ~]# awk '/Zhang/' t1.txt 
Zhang  Dandan    41117397    :250:100:175
Zhang  Xiaoyu    390320151   :155:90:201
# 查询Zhang、Lao所在的行信息
[root@m01 ~]# awk '/Zhang/;/Lao/' t1.txt 
Zhang  Dandan    41117397    :250:100:175
Zhang  Xiaoyu    390320151   :155:90:201
Lao    Nanhai    918391635   :250:100:175

# 显示Zhang的ID号
[root@m01 ~]# awk '/Zhang/ {printf $3"\n"}' t1.txt 
41117397
390320151
# 显示Zhang的捐款记录,$
[root@m01 ~]# awk '/Zhang/ {printf $NF"\n"}' t1.txt
:250:100:175
:155:90:201

# 显示所有以41开头的ID号码的人的全名和ID号码
[root@m01 ~]# awk '$3~/^41/{print $1,$2,$3}' t1.txt 
Zhang Dandan 41117397
Liu Bingbing 41117483

# 显示所有ID号码最后一位数字是1或5的人的全名
[root@m01 ~]# awk '$3~/1$|5$/ {print $1,$2}' t1.txt |column -t
Zhang  Xiaoyu
Wu     Waiwai
Wang   Xiaoai
Li     Youjiu
Lao    Nanhai 
# awk默认使用空格分割,使用-F指定分割符
[root@m01 ~]# awk '/Zhang/{print $NF}' t1.txt|awk -F ":" '{print $3}'
100
90

# BEGIN在最开始的时候执行,读取文件,NED在最后执行
[root@m01 ~]# awk '/Zhang/ {print $NF}' t1.txt |awk 'BEGIN{FS=":"}{print $3}END{print "我是最后执行的"}'
100
90
我是最后执行的

## 替换信息
# gsub(/需要替换的信息/,"修改成什么信息",将哪列信息进行修改)
[root@m01 ~]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print $NF}'    t1.txt
$155$90$201
awk '$0~/^$/ {gsub(/ /,/"-"/)};print $0'
## 排除信息
# 件中空行进行排除、文件中注释信息进行排除
[root@m01 ~]# cat t1.txt 
姓       名        ID          捐款记录
Zhang  Dandan    41117397    :250:100:175
Zhang  Xiaoyu    390320151   :155:90:201
#Meng   Feixue    80042789    :250:60:50
Wu     Waiwai    70271111    :250:80:75
Liu    Bingbing  41117483    :250:100:175
-----------------------------------------
Wang   Xiaoai    3515064655  :50:95:135
Zi     Gege      1986787350  :250:168:200
-----------------------------------------
Li     Youjiu    918391635   :175:75:300
-----------------------------------------
Lao    Nanhai    918391635   :250:100:175
-----------------------------------------
# 排除所有以#和-开头的信息
[root@m01 ~]# awk '$0!~/^#|^-/' t1.txt 
姓       名        ID          捐款记录
Zhang  Dandan    41117397    :250:100:175
Zhang  Xiaoyu    390320151   :155:90:201
Wu     Waiwai    70271111    :250:80:75
Liu    Bingbing  41117483    :250:100:175
Wang   Xiaoai    3515064655  :50:95:135
Zi     Gege      1986787350  :250:168:200
Li     Youjiu    918391635   :175:75:300
Lao    Nanhai    918391635   :250:100:175
## 统计信息
# 统计/etc/services文件中有井号开头的行
[root@m01 ~]# awk '/^#/{i++}END{print i}' /etc/services
102	
# 统计系统中有多少个虚拟用户 普通用户
[root@m01 ~]#  awk '$NF~/bash/{i=i+1}END{print i}' /etc/passwd
    63
# 虚拟用户数量
[root@m01 ~]#  awk '$NF!~/bash/{i=i+1}END{print i}' /etc/passwd
22

awk函数

awk 编程也允许在编程时使用函数

: << !
function 函数名(参数列表){ 
	函数体 
} 
!
# 删除t1.txt文件中的-
[root@localhost ~]# sed '/-/d' t1.txt  -i 
# 定义函数 test ,包含两个参数,函数体的内容是输出这两个参数,函数体是打印两个参数
# 调用函数 test ,并向两个参数传递值。
[root@m01 ~]# awk 'function test(a,b){printf a"\t"b"\n"} { test($1,$2) }' t1.txt |column -t
姓	   名
Zhang	Dandan
Zhang	Xiaoyu
#Meng	Feixue
Wu		Waiwai
Liu		Bingbing	
Zi		Gege
Wang	Xiaoai
Zi		Gege
Li		Youjiu	
Lao		Nanhai

awk调用脚本

对于小的单行程序来说,将脚本作为命令传递给 awk 是非常简单的,而对于多行程序就比较难处理。当程序是多行的时候,使用外部脚本是很适合的。首先在外部文件中写好脚本,然后可 以使用 awk 的-f 选项,使其读入脚本并且执行。

[root@m01 ~]# cat awk.sh 
#!/bin/bash
BEGIN{FS=":"}$3>=1000{print $0}

# 查找普通用户
[root@m01 ~]# awk -f awk.sh /etc/passwd
python:x:1000:1000:python:/home/python:/bin/bash
linux:x:1002:1002::/home/linux:/bin/bash
java:x:1003:1003::/home/java:/bin/bash

6. 管道命令 |

命令 1 的正确输出的结果作为命令 2 的操作对象

# 查看所有/etc下的文件,从中过滤包含yum的文件
[root@m01 ~]# ll /etc | grep yum
drwxr-xr-x.  6 root root      100 Dec 30 16:36 yum
-rw-r--r--   1 root root      970 May 25 10:59 yum.conf
drwxr-xr-x.  2 root root     4096 Jun  1 14:29 yum.repos.d

#查看22远程端口是否开启 
[root@m01 ~]# netstat -tulnp |grep 22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      985/sshd            
tcp6       0      0 :::22                   :::*                    LISTEN      985/sshd     
posted @ 2020-06-27 22:37  s小毛驴  阅读(396)  评论(0编辑  收藏  举报
返回顶部