Linux三剑客grep、sed、awk的使用
Linux正则表达式
正则表达式:Regual Expression, REGEXP
由一类特殊字符及文本字符所编写的模式,其中有些字符不表示其字面意义,而是用于表示控制或通配的功能;
基本正则表达式:BRE
扩展正则表达式:ERE
正则表达式的意义
通常Linux运维工作,都是面临大量带有字符串的内容,如:
命令输出结果
且此类字符串内容,我们常会有特定的需要,查找出符合工作需要的特定的字符串,因此正则表达式就出现了
正则表达式是一套规则和方法
正则工作时以单位进行,一次处理一行
正则表达式化繁为简,提高工作效率
linux仅受三剑客(sed、awk、grep)支持,其他命令无法使用
正则表达式应用非常广泛,应用在如Python、Java、Perl等,Linux下普通命令无法使用正则表达式的,只能使用三剑客。
Linux三剑客
文本处理工具,均支持正则表达式引擎
grep:文本过滤工具,(模式:pattern)工具,
擅长单纯的查找或匹配文本内容
sed:stream editor,流编辑器;文本编辑工具,
更适合编辑、处理匹配到的文本内容
awk:Linux的文本报告生成器(格式化文本),Linux上是gawk,
更适合格式化文本内容,对文本进行复杂处理
基本正则表达式BRE集合
全拼
:Global search REgular expression and Print out the line.
作用
:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,打印匹配到的行
模式
:由正则表达式的
元字符
及
文本字符
所编写出的
过滤条件
;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
语法:
grep [options] [pattern] file
命令 参数 匹配模式 文件数据
-A<显示行数>:除了显示符合范本样式的那一列之外,并显示该行之后的内容。
-B<显示行数>:除了显示符合样式的那一行之外,并显示该行之前的内容。
-C<显示行数>:除了显示符合样式的那一行之外,并显示该行之前后的内容。
-c:统计匹配的行数
-e :实现多个选项间的逻辑or 关系
-E:扩展的正则表达式
-f FILE:从FILE获取PATTERN匹配
-F :相当于fgrep
-i --ignore-case #忽略字符大小写的差别。
-n:显示匹配的行号
-o:仅显示匹配到的字符串
-q: 静默模式,不输出任何信息
-s:不显示错误信息。
-v:显示不被pattern 匹配到的行,相当于[^] 反向匹配
-w :匹配 整个单词
1 |
语法: |
1 |
grep -i -n "^i" lxz # -i忽略大小写 -n 显示仪行号 |
1 |
grep -i -n "^t" lxz |
1 |
grep -i -n "r$" lxz |
1 |
grep -i -n "m$" lxz |
1 |
1.注意不加转义符的结果,正则里"."是匹配任意1个字符,grep把.当做正则处理了,因此把有数据的行找出来了, |
^$
组合符
1 |
$ grep "^$" -n lxz |
.
点符号
.
点表示任意一个字符,有且只有一个,不包含空行
1 |
$ grep -i -n "." lxz |
匹配出
.li
,找出任意一个三位字符,包含li
1 |
$ grep -i -n ".li" lxz |
\
转义符
找出文中所有的点"."
1 |
$ grep "\." lxz |
找出前一个字符0次或多次,找出文中出现"i"的0次或多次
.*
符号
.
表示任意一个字符,
*
表示匹配前一个字符0次或多次,因此放一起,代表匹配所有内容,以及空格
1 |
grep '.*' lxz |
^.*o
符
^
以某字符为开头
.
任意0或多个字符
.*
代表匹配所有内容
o
普通字符,一直到字母o结束
这种匹配相同字符到最后一个字符的特点,称为贪婪匹配
[abc]
中括号
中括号表达式,[abc]表示匹配中括号中任意一个字符,a或b或c,常见形式如下
[a-z]匹配所有小写单个字母
[A-Z]匹配所有单个大写字母
[a-zA-Z]匹配所有的单个大小写字母
[0-9]匹配所有单个数字
[a-zA-Z0-9]匹配所有数字和字母
[^abc]
中括号中取反
[^abc]
或
[^a-c]
这样的命令,
^
符号在中括号中第一位表示排除,就是排除字母a或b或c
grep参数
-o
使用"-o"选项,可以只显示被匹配到的关键字,而不是讲整行的内容都输出。
显示文件中有多少个字符a
1 |
$ grep -o 'a' lxz | wc -l |
扩展正则表达式实践
使用
grep -E
进行实践扩展正则
+号表示匹配前一个字符1次或多次,必须使用grep -E 扩展正则
grep -E 'l+' lxz #匹配lxz文件中l字符一次或多次
匹配前一个字符0次或1次
1 |
grep -E 'ao?b' luffycity.txt |
竖线在正则中是
或者
的意思
1 |
find /home/lixingze -maxdepth 3 -name "*.txt" |grep -i -E "a|b" |
()
小括号
将一个或多个字符捆绑在一起,当作一个整体进行处理;
小括号功能之一是
分组过滤被括起来的内容
,
括号内的内容表示一个整体
括号()内的内容可以
后面的"\n"正则引用
,
n为数字
,表示
引用第几个括号的内容
\1
:表示从左侧起,第一个括号中的模式所匹配到的字符
\2
:从左侧期,第二个括号中的模式所匹配到的字符
分组案例:
找出,用户名,shell名相同的行
sed是Stream Editor(字符流编辑器)的缩写,简称流编辑器。
sed是操作、过滤和转换文本内容的强大工具。
常用功能包括结合正则表达式对文件实现快速增删改查,其中查询的功能中最常用的两大功能是过滤(过滤指定字符串)、取行(取出指定行)。
1 |
sed [选项] [sed内置命令字符] [输入文件] |
sed案例
准备测试数据
1 |
$ cat lxz |
1 |
$ sed -n '2,3p' lxz |
1 |
$ sed -n '/lxz9.com/p' lxz |
注:sed想要修改文件内容,使用-i参数
1 |
$ sed '/linux/d' lxz |
修改结果写入到文件
1 |
$ sed -i '/linux/d' lxz #不会输出结果,直接写入文件 |
删掉2,3两行
sed '2,3d' lxz
删除第5行到结尾
sed '5,$d' lxz
s内置符配合g,代表全局替换,中间的"/“可以替换为”#@/"等
1 |
$ sed 's/My/Her/g' lxz |
1 |
$ sed -e 's/My/Her/g' -e 's/lxz9/baidu/g' lxz |
1 |
$ sed -i '2a I am useing sed command' lxz |
添加多行信息,用换行符
\n
1 |
$ sed -i "2a abc.\nbcd." lxz |
在每一行下面插入新内容
1 |
$ sed "a ---" lxz |
sed '2i I am useing sed command' lxz
sed配合正则表达式案例
取出linux的IP地址
1 |
1.首先取出第二行 |
1
2
# ifconfig eth0 | sed -ne '2s/^.*inet//g' -e '2s/net.*$//gp'
10.141.32.137
1 |
# ifconfig eth0 | sed -ne '2s/^.*inet//g' -e '2s/net.*$//gp' |
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
awk是一个强大的linux命令,有强大的文本格式化的能力,好比将一些文本数据格式化成专业的excel表的样式
1 |
awk [option] 'pattern[action]' file ... |
awk使用
1 |
#示例文件内容如下 |
执行的命令是
awk '{print $5}'
,没有使用参数和模式,
$5
表示输出文本的
第五列
信息
awk默认以空格为分隔符,且多个空格也识别为一个空格,作为分隔符
awk是按行处理文件,一行处理完毕,处理下一行,根据用户指定的分割符去工作,没有指定则默认空格
$0表示整行 $NF表示当前分割后的最后一列 倒数第二列可以写成$(NF-1)
awk内置变量
一次性输出多列
1 |
$ awk '{print $1,$2}' awk_test |
自动定义输出内容
awk,必须外层单引号,内层双引号
内置变量
$1、$2
都不得添加双引号,否则会识别为文本,尽量别加引号
1 |
$ awk '{print "第一列",$1,"第二列",$2,"第五列",$5}' awk_test |
输出整行信息
1 |
awk '{print}' awk_test |
awk选项参数说明
1 |
-F fs or --field-separator fs |
显示文件第三行
1 |
#NR在awk中表示行号,NR==3表示行号是3的那一行 |
显示文件2-5行
1 |
$ awk 'NR==2,NR==5' awk_test |
给每一行的内容添加行号
添加变量,NR等于行号,$0表示一整行的内容
{print }是awk的动作
1 |
$ awk '{print NR,$0}' awk_test |
显示文件3-5行且输出行号
1 |
$ awk 'NR==3,NR==5 {print NR,$0}' awk_test |
显示文件的第一列,倒数第二和最后一列
1 |
awk -F ' ' '{print $1,$(NF-1),$NF}' pwd.txt |
awk分隔符
awk的分隔符有两种
FS输入分隔符
awk逐行处理文本的时候,以输入分割符为准,把文本切成多个片段,默认符号是空格
当我们处理特殊文件,没有空格的时候,可以自由指定分隔符特点
1 |
#准备示例文件,把之前的空格全部替换为任意符号,这里使用逗号 |
除了使用-F选项,还可以使用变量的形式,指定分隔符,使用-v选项搭配,修改FS变量
1 |
$ awk -v FS=',' '{print $1}' awk_test |
OFS输出分割符
awk执行完命令,默认用空格隔开每一列,这个空格就是awk的默认输出符,例如
1 |
$ cat awk_test |
输出分隔符与逗号
awk是否存在输出分隔符,特点在于
'{print $1,$3 }
逗号的区别
1 |
$ awk -v FS=',' '{print $1,$3}' awk_test |
1 |
$ awk -v FS=',' '{print $1$3}' awk_test |
1 |
awk -v FS=',' -v OFS='\t' '{print $1,$3 }' awk_test |
awk变量
对于awk而言,变量分为:
自定义变量
1 |
# sed将逗号替换为空格 |
输出每行行号,以及指定的列
1 |
$ awk '{print NR,$1,$5}' awk_test |
处理多个文件显示行号
1 |
# 普通的NR变量,会将多个文件按照顺序排序 |
内置变量ORS
ORS是输出分隔符的意思,awk默认认为,每一行结束了,就得添加回车换行符
ORS变量可以更改输出符
1 |
$ awk -v ORS=';;;' '{print NR,$0}' awk_test |
内置变量FILENAME
显示awk正在处理文件的名字
1 |
$ awk '{print FILENAME,FNR,$0}' awk_test test1 test2 |
变量ARGC、ARGV
ARGV表示的是一个数组,数组中保存的是命令行所给的参数
数组是一种数据类型,如同一个盒子
盒子有它的名字,且内部有N个小格子,标号从0开始
给一个盒子起名字叫做months,月份是1~12,那就如图所示:
自定义变量
方法一:
-v
varName=value
1 |
$ awk -v lxz9com="我的网址lxz9.com" 'BEGIN{print lxz9com}' |
方法二:在程序中直接定义
1 |
$ awk 'BEGIN{abc="字母abc";def="字母def";print abc,def}' |
awk格式化
printf和print的区别
format的使用
1、其与print命令的最大不同是,printf需要指定format;2、format用于指定后面的每个item的输出格式;
3、printf语句不会自动打印换行符;\n
format格式的指示符都以%开头,后跟一个字符;如下:
%c: 显示字符的ASCII码;
%d, %i:十进制整数;
%e, %E:科学计数法显示数值;
%f: 显示浮点数;
%g, %G: 以科学计数法的格式或浮点数的格式显示数值;
%s: 显示字符串;
%u: 无符号整数;
%%: 显示%自身;
printf修饰符:
-: 左对齐;默认右对齐,
+:显示数值符号; printf “%+d”
1 |
$ awk '{print $1}' awk_test |
给printf添加格式
1 |
$ awk '{printf "%s\n",$1}' awk_test |
对多个变量进行格式化
1 |
$ printf "%s\n" a b c d |
1 |
$ awk 'BEGIN{printf "%d\n%d\n%d\n%d\n%d\n",1,2,3,4,5}' |
printf对输出的文本不会换行,必须添加对应的格式替换符和\n
使用printf动作,
'{printf "%s\n",$1}'
,替换的格式和变量之间得有逗号,
使用printf动作,%s %d 等格式化替换符 必须 和被格式化的数据一一对应
awk模式
1 |
awk [option] 'pattern[action]' file |
awk是按行处理文本
1 |
$ awk 'BEGIN{print "lxz9.com"}{print $1}' awk_test |
没有指定任何的模式(条件),因此每一行都执行了对应的动作,空模式会匹配文档的每一行,每一行都满足了(空模式)
1 |
$ awk '{print $1}' awk_test |
关系运算符模式
awk默认执行打印输出动作
1 |
$ awk 'NR==2,NR==5' awk_test |
BEGIN/END模式(条件设置)
1 |
$ awk 'BEGIN{print "我在开头位置"}{print $1,$2}END{print "我在结尾处"}' awk_test |
awk与正则表达式
正则表达式主要与awk的pattern模式(条件)结合使用
不指定模式,awk每一行都会执行对应的动作
指定了模式,只有被模式匹配到的、符合条件的行才会执行动作
找出a文件中有以export开头的行
1 |
$ grep '^export' a |
1 |
$ awk '/^export/{print $0}' a |
awk使用正则语法
grep ‘正则表达式’ a.txt
awk ‘/正则表达式/动作’ a.txt
(下面内容以/etc/passwd文件为例)
1 |
$ cat -n passwd |
找出passwd文件中禁止登录的用户(/sbin/nologin)
正则表达式中如果出现了
"/"
则需要进行转义
找出pwd.txt文件中禁止登录的用户
(/sbin/nologin)
1 |
grep '/sbin/nologin$' passwd |
/正则表达式/
1 |
awk '/\/sbin\/nologin$/{print $0}' passwd |
找出文件的区间内容
找出adm用户到mail用户之间的内容
awk '/正则表达式/{动作}' file
行范围模式
awk '/正则1/,/正则2/{动作}' file
1 |
$ awk '/^adm/,/^mail/ {print $0}' passwd |
关系表达式模式
1 |
$ awk 'NR>=4 && NR<=9 {print $0}' passwd |
推荐学习相关计算机网课
路飞学城