Linux:管道、正则表达式,grep、sed、awk命令

本文介绍了Linux系统中常用的文本处理命令grep、sed和awk的用法,包括正则表达式的基本语法、grep的搜索功能、sed的文本编辑和替换以及awk处理列数据的能力。通过实例展示了这些命令的实际应用,如查找特定模式、行处理和日志分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux:grep、sed、awk命令

正则表达式:匹配字符串

sed:擅长文本处理和文件内容替换

grep:擅长搜索信息

awk:擅长处理列数据和替换内容

------------------------------------------------------------------------------------------------------------------------------

正则表达式基本语法:

在线正则表达式测试网址:https://tool.oschina.net/regex/

\bture\b:查找true单词,前后用\b包住

\bHi\b.*\btom\b:查找‘Hi * tom’这个格式的字符串,*表示中间为任意字符

0\d{2}-\d{8}:查找010-12345678格式的电话号码

正则表达式字符意义
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\b匹配单词的开始或结束
\d匹配数字
^

匹配字符串的开始

$匹配字符串的结束
*重复零次或者更多次前一个字符
+重复一次或更多次
重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
()分组,在后面sed命令的练习中有使用到
|匹配多个表达式中的任何一个,查找多个表达式,表达式中间用|符号隔开
非贪婪匹配

练习:

匹配以字符a开头的单词:\ba\w*\b

匹配刚好6个字符的单词:\b\w{6}\b

匹配1个或者更多连续的数字:\d+

匹配5到12位数字:\d{5,12}   or  ^\d{5,12}$(只匹配数字,防止q11111也能被匹配到)

grep命令:

根据用户指定的规则,对目标文本进行过滤,显示被规则匹配到的行信息,这个规则是支持正则表达式的,因此grep中可以使用正则表达式

命令形式:grep [options] pattern [file]

-v  显示不被匹配规则匹配到的行,相当于反向匹配,默认是显示匹配到的行
-i  忽略字符的大小写
-n  显示匹配的行号
-c  统计匹配的行数
-o  仅显示匹配到的字符串
-E  使用扩展的正则表达式ERE,相当于egrep
-r:grep pattern -r dir  递归搜索
grep --line-buffered 强制输出结果

-A  查看当前查找信息的后面行信息,-A 1代表查看后面一行,-A 2代表查看后面两行,以此类推

-B  查看当前查找信息的前面行信息

-C  查看当前查找信息的上下文,即前面信息和后面的行信息,使用方法同-A

练习:

grep root 1.txt: 查找1.txt文件中包含root字符的行,并打印在控制台上

grep -o root 1.txt: 查找1.txt文件中包含root字符,但只打印匹配到的root字符串

grep -v root 1.txt: 查找1.txt文件中不包含root字符的行

grep -vn root 1.txt: 查找1.txt文件中不包含root字符的行,并打印出行号

grep ^s 1.txt: 查找1.txt文件中以s字符开头的行

多重管道grep使用时可以使用grep --line-buffered进行强制输出给下一个管道命令使用:

 ping 114.114.114.114 | grep --line-buffered 2 |grep 5

grep -A等参数的使用练习:

grep 'root' /etc/passwd

grep -n -A 2 'root' /etc/passwd

如果在pattern中想使用扩展的正则表达式,需要使用-E参数进行扩展,比如查找多个关键字:

grep -E 'root|games' /etc/passwd

sed命令:

sed是流编辑器,一次处理一行内容,sed处理流程:一行存储在模式空间,然后使用sed命令处理,处理完成后显示到屏幕,清空模式,继续导入后面的行循环处理

sed命令和grep类似,但是比grep命令多一些文件操作:增加、删除、修改,命令形式为:

sed [-hn..] [-e<script>] [-f<script file>] [file]

-h  显示帮助

man sed  显示帮助

-n  静默模式,仅显示script处理后的结果

-e  以指定的script来处理输入的文本文件 【默认为-e,可以省略】

-E  使用扩展的表达式:扩展的正则表达式

-f  以指定的script文件来处理输入的文本文件
-i  将改动写入源文件

a:新增  sed -e '4a newline':在第四行后面新增加一行,内容为newline【-e参数可以省略】

c:取代  sed -e '2,5c No 2-5 number':使用No 2-5 number内容去取代2-5行的内容,相当于2-5这四行变成一行内容

d:删除  sed -e '2,5d':删除2-5行
i:插入  sed -e '2i newline':在第二行前面插入一行,内容为newline
p:打印  sed -n '/root/p':匹配到两个斜杠里面的内容并打印,两个斜杠之间的内容是支持正则表达式的
s:取代  sed -e 's/old/new/g':使用new去替代old,/g表示全局替代,不加g参数的话,每行只会替代第一个匹配到的字符串,如果关键字中包含/那么可以使用@或者#符去替代/,那么就不用使用转义符进行转义了

特殊用法的练习:

-i参数的特殊用法:

sed -i.bak 's/abc/ABC' filename  -i.bak表示修改源文件之前,将源文件复制一份并命令为filename.bak进行备份保存

分组匹配与字段提取:

echo "12ab34cd" |sed -E 's#([0-9]*)([a-z]*).*#\1 \2#'

解析:具体不懂,大概就是-E支持扩展的表达式,s代表替换,#([0-9]*)([a-z]*).*#\1 \2#三个#号之间,前面两个#号之间匹配到的字符串用后面两个#号的字符替换,同时\1和\2分别表示两个()中的内容吧

这个的高端用法是可以跟bash命令结合一起使用:

ls *.txt|sed -E 's/(.*).txt/\1/'

ls *.txt|sed -E 's/(.*).txt/\1.log/'

awk命令:

awk命令把文件逐行的读入,以空格为默认分割符将每行切片,切开的部分再进行后续处理

处理过程:把行作为输入并赋值给$0变量,这是一个内置变量;然后将行切片,将切片的值从$1($2,$3,...,$n)开始赋值,对行匹配正则/执行动作,打印内容,然后循环导入下一行进行操作

命令形式为:awk 'pattern+action' [file]

-pattern:正则表达式

-action:对匹配到的内容执行的命令(默认为输出每行内容)

常用参数:

awk 'pattern{action}'  命令表达式

awk 'BEGIN{}END{}'  开始和结束

awk '/root/'  正则匹配//之间的内容

awk '/aa/,/bb/'  区间选择

awk '$2~/xxx/'  字段匹配

awk 'NR==2'  取第二行信息

awk 'NR>1'  去掉第一行

fflush()  刷新缓存

BEGIN{FS=':'}  表示指定分隔符为:

$0 代表当前记录

$NF  代表最后一个域

$(NF-1)  代表倒数第二个域

-F  指定字段的分隔符,可以用|指定多个可能的分隔符 -F '<|>',指定了<或者>字符为分隔符

echo "12#34@45%89" |awk -F '#|@|%' '{print $1}' 

练习:

多个管道中使用命令,如果时awk命令的话,需要使用到fflush()方法,这样数据才能传给下一个管道命令

 ping 114.114.114.114 |awk -F = '{print $4;fflush()}' |grep 7

awk行处理:把单行拆分为多行:echo $PATH|awk 'BEGIN{RS=":"}{print NR,$0}'

awk行处理:把多行组合为单行:echo $PATH|awk 'BEGIN{RS=":"}{print $0}'|awk 'BEGIN{ORS="@@"}{print $0}'

FILENAME  awk浏览的文件名OFS  输出域分隔符
BEGIN  处理文本之前要执行的操作,类似pytest里面的setupORS  输出记录分隔符
END  处理文本之后要执行的操作,类似pytest里面的teardownRS  控制记录分隔符,默认为换行符,使用RS可以设置控制记录的分隔符
FS  设置输入域的分隔符,等价于命令行的-F选项$0  整条记录
NF  浏览记录的域的个数(列数)$1  当前行的第一个域,$2当前行的第二个域,以此类推
NR  已读的记录数(行数) 

搜索/etc/passwd有关root关键字的所有行,并显示对应的shell,awk -F : '/root/ {print $7}' /etc/passwd

-F :   代表使用冒号来作为输入域的分隔符,而不是使用默认的空格符

/root/:表示查找正则表达式root

{print $7}:匹配到合适的行后,打印该行的第七个域内容

打印/etc/passwd的第二行信息 ,awk -F : 'NR==2 {print $0}' /etc/passwd

NR==2:获取第二行的信息

{print $0}:打印第二行的整条记录

使用BEGIN加入标题,awk -F : 'BEGIN{print "BEGIN","BEGIN"}{print $1,$2}' /etc/passwd

自定义分隔符,echo "123|456|789"|awk 'BEGIN{RS="|"} {print $0}'

"123|456|789"这个字符串设置|为分隔符,分隔成了三行

ngix日志分析相关命令:

cat:查看文本内容

wc:统计字符、行数、byte自己信息呀啥的。man wc查看帮助  wc -l filename统计行数

sort:排序

uniq:去重

head:查看文件前n行,默认为10行

uniq去重命令练习:增加-c参数可以统计相同数据出现的次数,如果数据不是挨在一起,就不能完全去重

awk '{print $7}' nginx.log |sed -E 's#/topics/[0-9]*#/topics/int#g;s#/replies/[0-9]*#replies/int#g;s#([0-9a-z-]*).png#int.png#g;s#([0-9a-z-]*).jpg#int.jpg#'|sort|uniq -c|sort -nr|head -20

 

 

 

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值