Linux三剑客
正则表达式
在讲linux三剑客之前,我们先来了解一下正则表达式。
什么是正则表达式?
基本正则表达式(BRE)
BRE对应元字符有:^ $ . [] *
- 匹配字符
- 匹配次数
- 位置锚定
符号 | 作用 |
---|---|
^ | 用于模式最左侧,如“^abcd”,匹配以abcd开头的行 |
$ | 用于模式最右侧,如“abc$”,匹配以abc结尾的行 |
^$ | 组合符,表示空行 |
. | 匹配任意一个且只有一个字符(任意一个字符),不能匹配空行 |
\ | 转义字符,例如‘.’表示小数点 |
* | 匹配前一个字符0次或1次以上 |
.* | 组合符,匹配所有内容 |
^.* | 匹配任意多个字符开头的内容 |
.*$ | 匹配任意多个字符结尾的内容 |
[abc] | 匹配[]集合中任意一个字符,a或b或c,可以写[a-c] |
[^abc] | 匹配除了^后面的任意字符 |
扩展正则表达式
ERE在BRE的基础上,增加上 :() {} ? + |
扩展正则必须使用 grep -E 才能生效
字符 | 作用 |
---|---|
+ | 匹配前面字符一次或多次 |
[ ]+ | 匹配括号内的字符一次或多次 |
? | 匹配一个字符0次或1次 |
| | 表示或者,同时过滤多个字符串 |
() | 分组过滤,括号内表示一个整体 |
a{n,m} | 表示匹配a(可更换)字符最少n次,最多m次 |
a{n,} | 匹配最少n次 |
a{n} | 匹配正好n次 |
a{,m} | 匹配最多m次 |
三剑客
- grep : 文本过滤工具,行过滤
- sed: 对文件或是数据流进行加工处理,操作,过滤转换文本
- awk: 格式化文本内容,对文本进行复杂处理
grep与正则表达式:按行匹配
作用:文本搜索工具,根据用户指定的模式对目标文本进行匹配检查,打印匹配到的行
grep [options] [pattern] file
命令 参数 匹配模式 文件
常见的参数:
- -i : 忽略大小写
- -n:显示匹配行的行号
- -c : 只统计匹配的行数
- -w:只匹配过滤的单词
- -o : 仅显示匹配到的字符串本身(默认整行输出)
- -v : 排除匹配结果,显示不能被匹配到的行
- -E: 支持使用扩展的正则表达式
案例:
grep “root” ./pwd.txt -i
: 查找pwd.txt文件中包含root的行grep “^$” space.txt -v
:查找space.txt文件中的非空行grep “^$” space.txt -v | grep “^#” -v
: 查找文件中的非空行和非#号开头的行注意在管道符后面的grep中不需要加文件名
grep "\.$" space.txt -n
:查找以 . 结尾的行注意.符号为匹配任意一个有且只有一个字符,不匹配空行。所以需要用 \ 符号
grep ".b" space.txt -n
:查找包含"(任意字符)b"格式的行可以将. 理解为任意一个字符
grep "q*" space.txt -n
: 出现q的行,0次1次或多次贪婪匹配
grep “.*e” space.txt -n
:以e结尾,无论前面是什么
注意只有‘.*’ 是匹配全部
[abc]:表示匹配括号中任意一个字符
[a-z]
匹配所有小写单个字母[A-Z]
:匹配所有单个大写字母[a-zA-Z]
:匹配所有单个大小写字母[0-9]
:匹配所有单个数字[a-zA-Z0-9]
:匹配所有数字和字母案例:
-
grep "[a-eA-C0-3]" space.txt
:匹配a-e和A到C和0-3的字符
-grep "[^0-3]" space.txt
:匹配存在除0-3以外字符的行
扩展正则表达式的使用
使用grep -E进行使用扩展正则
+:匹配前面字符一次或多次
grep -E "i+" pwd.txt
:匹配出现i字符一次或多次的行
grep -E "abi+" pwd.txt
:匹配出现abi字符一次或多次的行注意在+号前有多个字符时,将其看为一个整体去匹配
?:匹配前面字符0次或1次
grep -E "go?d" test.txt
:匹配g和d之间出现0次或一次o符号的行
|:或
grep -E "a|b" test.txt
: 匹配出现字符a或b的行
()
将括号里面内容当作整体
括号里面内容可以被后面的
\n
作为正则引用,n
为数字,表示引用第几个符号。\1
:表示从左起,第一个括号中模式所匹配到的字符\2
:表示从左起,第二个括号中模式所匹配到的字符
找出包含good和glad 的行
grep -E ”good | glad“ test.txt
- 或者
grep -E "g(oo | la)d" test.txt
- 找出 "love .* love "格式的行
grep -E "(love).*\1"
:(love) 匹配love,.* 表示任意字长度符,\1表示引用第一个括号中内容
(n,m):匹配次数
grep -E "y{2,4}" test.txt
:匹配y字符最少两次最多四次的行
sed与正则表达式
注意sed 和awk使用单引号,双引号有其他特殊解释
sed常用功能包括结合正则表达式对文本实现快速的增删查改,其中查询功能中最常见的两大功能是过滤(过滤指定字符串),取行(取出指定行)
sed详细工作流程:
语法:
sed [选项] [sed内置命令字符] [输入文件]
sed的内置命令用于对文件进行不同的操作功能,例如对文件的增删查改
选项
参数选项 | 解释 |
---|---|
-n | 取消默认sed的输出,常与sed内置命令p一起用 |
-i | 直接将修改结果写入文件,不用-i,sed修改的是内存数据 |
-e | 多次编辑,不需要管道符了 |
-r | 支持正则扩展 |
sed常用的内置命令字符
sed常用内置命令字符 | 解释 |
---|---|
a | append,对文本追加,在指定行后面添加一行/多行文本 |
d | delete,删除匹配行 |
i | insert,表示插入文本,在指定行前插入一行/多行文本 |
p | print,打印匹配行的内容,通常p与-n一起使用 |
s/正则/替换内容/g | 匹配正则内容,然后替换内容(支持正则),结尾g代表全局匹配 |
sed匹配范围
范围 | 解释 |
---|---|
空地址 | 全文处理 |
单地址 | 指定文件某一行 |
/pattern/ | 被模式匹配到的每一行 |
范围区间 | 10,20 表示十到二十行;10,+5 表示十行向下五行 |
步长 | 1~2 表示1,3,5,7,9行;2~2表示2,4,6,8,10行 |
案例
输出文件第2,3行
sed '2,3p' -n test.txt
p与-n常一起使用,p为print,-n为取消sed默认输出
过滤出含有linux的字符串行
sed '/linux/p' -n test.txt
sed中匹配范围时用/pattern/
删除有compute的行
sed '/game/d' test.txt -i
添加-i参数会直接将修改结果写回文件
删除第五行到结尾行
sed '5,$d' test.txt -i
将文件中全部my替换为his
sed 's/my/his/g' 1.txt -i
s/你想找的内容/想替换的内容/全局替换
替换所有的his为my,同时替换QQ号(多次替换)
sed -e 's/his/my/g' -e 's/12345/123/g' -i test.txt
多次替换中必须是-e在前,’s///‘在后
在文件的第二行下面追加内容"and games"(后面新增一行)
sed '2a and games' -i test.txt
在文件的第六行前面插入"and games"(前面新增一行)
sed '6i and games' -i test.txt
在文件的第三行前面插入"and games" ,“123” 两行数据(新增多行)
sed '3i and games\n 123' -i test.txt
在每一行下面添加 "-----------------"行(空地址)
sed 'a --------------------' -i test.txt
取出eth0中ip地址
ifconfig eth0
: 取出第一块内容sed '2p' -n
:取出第二行内容sed 's/^.*inet//'
: inet之前且包含inet的内容替换为空格sed 's/net.*$//'
:将net之后且包含net的内容替换为空格将以上三个步骤用管道符联合或者用-e参数多次编辑
用管道符号:
ifconfig eth0 | sed '2p' -n | sed 's/^.*inet// | sed 's/net.*$//'
用-e参数:
ifconfig eth0 | sed -e '2s/^.*inet//' -e '2s/net.*$//' -e '2p' -n
, 其中,sed '2s///' 表示对第2行进行操作
awk与正则表达式
awk [option] ‘pattern[action] file …’
awk 参数 ’条件动作‘ 文件
action
指的是动作,awk擅长文本格式化,且输出格式化后的结果,因此最常用的动作就是 print
和printf
awk '{print $2}'
: 没有使用参数和模式,输出文本的第二列信息
$2
表示第二列,$0
表示一整行awk
默认以空格为分隔符,且多个空格视为一个空格awk
是按行处理文件,一行处理完处理下一行$NF
表示当前分割的最后一列,倒数第二列可以写成$(NF-1)
awk 内置变量
内置变量 | 解释 |
---|---|
$n | 指定分隔符后,当前记录的第n个字段 |
$0 | 整行 |
FS | 字段分隔符,默认为空格 |
OFS | 输出字段分隔符,默认为空格 |
RS | 指定输入时的换行符 |
ORS | 指定输出时的换行符 |
NF | 分割后,当前一共有多少字段 |
NR | 行号 |
FNR | 各文件分别计数的行号 |
FILENAME | 当前文件名 |
ARGC | 命令行参数的个数 |
ARGV | 数组,保存的是命令行所给定的各参数 |
awk 功能参数
参数 | 解释 |
---|---|
-F | 指定分隔符 |
-v | 定义或修改一个awk内部的变量,如NF,FS |
-f | 从脚本文件中读取awk命令 |
案例
一次性输出多列
awk '{print $1,$2,$5}' test.txt
- 如果为
$1$2$5
则输出没有空格 - 可以自定义列顺序,例如:
$5,$3,$1
,则输出的列也会相应排列
- 如果为
自定义输出内容
awk必须外层单引号,内层双引号
内置变量 $1 、$2 都不得添加双引号,否则会识别为文本
取出文件第五行
NR在awk中表示行号,NR==5表示行号为5的那一行
:awk 'NR==5{print $0}' test.txt
其中NR==5表示模式,即选择的行区域;{print $0}表示动作
取出多行文件
awk 'NR==3,NR==10{print $0} test.txt'
:表示整行取出从第3行到第10行内容增添行号:使用内置变量
awk '{print NR,$0}' test.txt
: NR为内置变量,使用不需要加$输出37到40行内容并加上行号
awk 'NR==37,NR==40{print NR,$0}' test.txt
显示文件的第一列,倒数第二和最后一列
awk {print $1,$(NF-1),$(NF)} test.txt
取ip地址
ifconfig eth0 | awk 'NR==2{print $2}'
分隔符
awk的分隔符有两种:
- 输入分隔符,默认值为空格,变量名为FS
- 输出分隔符,简称为OFS
更改输入分隔符
使用其他分隔符,如#号:awk -F '#' '{print $1,$NF}' pwd.txt
或者使用更改变量参数:awk -v FS='#' '{print $1,$NF}'
更改输出分隔符
awk执行完命令,默认用空格隔开每一列,这个空格即为awk的默认输出符awk -F '#' -v OFS='---' '{print $1,$NF}' pwd.txt
awk变量
FNR变量
awk ’{print NR,$1}‘ pwd.txt test.txt
:普通的NR变量会将多个文件按照文件顺序排序awk '{print FNR,$1}' pwd.txt test.txt
: FNR变量,将会分别对文件进行计数
RS(输入分隔符)和ORS(输出分隔符)变量
awk -v RS=' ' '{print NR,$0}' test.txt
: 见到空格就换行awk -v ORS='--------\n' '{print NR,$0}' test.txt
:将--------添加至每行结尾
FILENAME变量(当前文件名称)
awk -F ':' '{print FILENAME,NR,$0}' pwd.txt
变量ARGC、ARGV
ARGV表示一个数组,数组中保存的是命令行给的参数
awk 'BEGIN{print "开始使用wak"}{print ARGV[0],ARGV[1],ARGV[2]}' pwd.txt test.txt
:先执行BEGIN中的内容自定义变量
awk -v myname="tanging" 'BEGIN{print "my name is ",myname}'
间接引用shell变量
1
2myname=“yuanyuan”
awk -v awk_myname=$myname 'BEGIN{print awk_myname}'
awk格式化
printf格式化输出
printf与print的区别
1 | format的使用 |
给printf添加格式
- 格式化字符串 %S 代表字符串的意思
awk ’{printf "%s\n,$1"}‘ pwd.txt
- 例子:对pwd.txt文件进行格式化
1 | awk -F ':' 'BEGIN{printf "%-25s\t%-25s\t%-25s\n","用户名","密码","UID"}{printf "%-25s\t%-25s\t%-25s\n",$1,$2,$3}' pwd.txt |
awk模式
awk语法:
awk [option] ‘pattern[action] file’
- 特殊的pattern : BEGIN 和 END
- BEGIN模式是处理文本之前需要执行的操作
- END模式是处理完所有行之后要执行的操作
1 | awk -F ':' 'BEGIN{print "处理前"}{print $1}END{print "处理后"}' pwd.txt |
- awk模式pattern也可以理解为条件,不指定任何模式则默认按行处理,如果指定了模式则只有符合模式的才会被处理
关系运算符 | 解释 |
---|---|
< | 小于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
>= | 大于等于 |
> | 大于 |
~ | 匹配正则 |
!~ | 不匹配正则 |
- awk模式总结
空模式,没有指定任何模式,按行运行
awk '{print $0}' pwd.txt
关系运算符模式
awk 'NR==2,NR==5{print $0}' pwd.txt
:读取第二行到第五行内容BEGIN/END模式
awk -F ':' 'BEGIN{print "处理前"}{print $1}END{print "处理后"}' pwd.txt
awk与正则表达式
正则表达式主要与awk的pattern模式结合使用
awk使用正则语法
awk '/正则表达式/动作' file
: awk命令使用正则表达式,必须把正则放入’//'双斜杠中
awk命令执行流程
awk 'BEGIN{commands} pattern{commands} END{commands}'
- 优先执行
BEGIN{}
中的语句 - 根据模式
pattern
执行commands - 执行
END{}
中命令
- 优先执行
筛选pwd.txt文件中有root开头的行的第一列和最后一列
awk -F ':' '/^root/{print $1,$NF}' pwd.txt
筛选pwd.txt文件中以/sbin/nologin结尾的行
awk -F ':' '/\/sbin\/nologin$/{print $0}' pwd.txt
:添加转义符
- 找出文件的区间内容
正则模式: awk '/正则表达式/{动作}/ file'
行范围模式: awk '/正则1/,/正则2/{动作}' file
:第一个正则为提取行首,第二个正则为提取行尾- 找出mail用户到nobody用户之间的内容
awk '/^mail/,/^nobody/{print $0}' pwd.txt
- 统计访客数量
awk '{print $1}' access.log | sort -n | uniq | wc -l
- 找出访问最频繁的前十个ip
awk '{print $1}' access.log | sort -n | uniq -c | sort -nr | head -10
- 找出mail用户到nobody用户之间的内容