Linux中grep, sed 和 awk的详细使用方法

Linux中grep, sed 和 awk的详细使用方法


Linux系统中grep, sed 和 awk被称作Linux文本三剑客,熟练使用这些工具会极大提升我们对文本操作的效率。由于Linux文本三剑客以正则表达式为基础,所以我们首先介绍正则表达式。

一、正则表达式介绍

正则表达式(Regular Expression,简写为RE、RegExp),又称为正规表示法、常规表示法等,是为处理大量的字符串而定义的一套规则和方法。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串,并可对匹配的字符串进行替换、取出等一系列操作。

1. 基本正则表达式

  • 字符匹配
元字符含义
.匹配任意单个字符,不能匹配空行
[]匹配指定范围的任意单个字符
[^]取反,匹配非指定范围的任意单个字符
[:alnum:] = [0-9a-zA-Z]字母与数字
[:alpha:] = [a-zA-Z]字母
[:upper:] = [A-Z]大写字母
[:lower:] = [a-z]小写字母
[:digit:] = [0-9]数字
[:ascii:]ASCII字符
[:blank:]空格或制表符
[:cntrl:]ASCII控制字符
[:graph:]非控制、非空格字符
[:print:]可打印字符
[:punct:]标点符号字符
[:space:]空白字符,包括垂直制表符
[:xdigit:]十六进制数字
  • 次数匹配
元字符含义
*匹配前面的字符0次或多次,一般结合 . 使用
.*匹配任意字符1次或多次
?匹配前面的字符0次或1次
\+匹配前面的字符1次或多次
x\{n\}匹配 x 出现次数为n
x\{n,\}匹配 x 出现次数至少为n
x\{,m\}匹配 x 出现次数至多为m
x\{n,m\}匹配 x 出现次数至少n,至多为m
  • 位置匹配
元字符含义
^只匹配行首
$只匹配行尾
\<锚定词首,用于单词的最左侧
\>锚定词尾,用于单词的最右侧
^$匹配空行
^[[:space:]].*$匹配带空格的空行
  • 分组和引用
元字符含义
\(\)分组;将一个或多个字符捆绑在一起,当成一个整体
\1向后引用;表示从左起第一个括号内所匹配到的字符
\2向后引用;表示从左起第二个括号内所匹配到的字符
\&向后引用;表示前面分组中的所有字符

2. 扩展的正则表达式

  • 字符匹配
元字符含义
.匹配任意单个字符,不能匹配空行
[]匹配指定范围的任意单个字符
[^]取反,匹配非指定范围的任意单个字符
a|b匹配a或者b
  • 次数匹配
元字符含义
*匹配前面的字符0次或多次
?匹配前面的字符0次或1次
+匹配前面的字符1次或多次
{n}匹配前面的字符n次
{n,m}匹配前面的字符至少n次,至多m次
  • 位置匹配和引用
元字符含义
^只匹配行首
$只匹配行尾
\<锚定词首,用于单词的最左侧
\>锚定词尾,用于单词的最右侧
()分组
\1向后引用

注:除了\<:词首; \>:词尾; \1:引用;使用扩展正则表达式时可以去掉\

二、grep用法介绍

grep 是 Global Regular Expression Print 的缩写,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配到的行打印出来,但不能替换匹配到的内容。

1. 命令格式

grep [option] '[PATTERN]' filename

2. 常用选项

-e: 实现多个选项的 or 逻辑,即或者关系
-E: 使用扩展的正则表达式,等于egrep
-i --ignore-case: 忽略大小写
-n: 显示匹配的行号
-v: 显示未被pattern匹配到的行,相当于[^]的反向匹配
-c: 统计匹配的行数
-F: 等于fgrep
-A2: 显示匹配行及后面2行
-B3: 显示匹配行及前面3行
-C1: 显示匹配行及前后1行
-o: 仅显示匹配到的字符串
-f file: 从file获取pattern的匹配
-q: 静默模式,不输出任何信息

3. grep用法实例

  • 简单用法
mxwang@mxwang:~$ cat test.txt 
Hello World!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ grep -C1 Linux test.txt   # 显示匹配Linux行及前后1行
Hello World!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ grep -c Hello test.txt   # 显示匹配Hello的行数
3
mxwang@mxwang:~$ grep -in hello test.txt   # 显示匹配hello的行及行号,且不区分大小写
1:Hello World!
2:Hello Linux! Hello Linux!
3:Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ grep -e Linux -e Python test.txt   # 显示匹配Linux或Python的行
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
  • 结合正则表达式的用法
mxwang@mxwang:~$ cat test.txt
123456
abcdefg
ABCDEFG
K
OK
      # 该行有三个空格
OOOK
mxwang@mxwang:~$ grep [0-9a-z] test.txt   # 显示匹配数字或小写字母的行
123456
abcdefg
mxwang@mxwang:~$ grep [^a-zA-Z] test.txt   # 显示没有字母的行
123456
   
mxwang@mxwang:~$ grep -n [[:space:]] test.txt   # 显示有空格的行及行号
6:   
mxwang@mxwang:~$ grep "O*K" test.txt   # 显示K前面有0个或者多个O的行
K
OK
OOOK
mxwang@mxwang:~$ grep "O.*K" test.txt   # 显示K前面有1个或者多个O的行
OK
OOOK
mxwang@mxwang:~$ grep "O\?K" test.txt   # 显示K前面有0个或者多个O的行
K
OK
OOOK
mxwang@mxwang:~$ grep -E "O+K" test.txt   # 开启扩展的正则表达式,显示K前面有1个或者多个O的行
OK
OOOK
mxwang@mxwang:~$ egrep "O{1,3}K" test.txt   # 开启扩展的正则表达式,显示K前面有1-3个O的行
OK
OOOK
mxwang@mxwang:~$ grep "\<O.*K\>" test.txt   # 显示包含单词以O开头K结尾的行
OK
OOOK
mxwang@mxwang:~$ grep "\<\(O\).\1K\>" test.txt   # 向后引用,显示包含单词以O开头K结尾,且K前面是O的行
OOOK

三、sed用法介绍

sed是 Stream EDitor 的缩写,是一个面向字符流的非交互式编辑器,按行来处理文本内容,主要用来自动编辑一个或多个文件,简化对文件的反复操作。sed把每一行都存在临时缓存区中,对这个副本进行编辑,所以不会修改或破坏源文件。

1. 命令格式

sed [option] 'sed command' filename   # 命令格式
sed [option] -f scriptfile filename   # 脚本格式

2. 常用选项

-n: 只打印模式匹配的行;
-e: 可进行多点编辑;
-f: 将sed的命令写在一个文件内,用 –f scriptfile 执行scriptfile内的sed操作;
-i: 直接修改文件内容;
-i.bak: 在将处理结果写入文件之前先备份文件
-r: 支持扩展的正则表达式;

3. 文本定位命令

定位命令含义
不给定位置,表示对全文进行处理
nn为行号,对指定行进行处理
n,m从n到m行
/pattern/匹配该模式的行
/pattern1/,/pattern2/匹配pattern1或者pattern2的行
/pattern/,n匹配到该模式的行到第n行,如果第n行后面有匹配该模式的也将得到匹配
n,/pattern/第n行到匹配到该模式的行(不再检测第n行是否匹配该模式,直接检测下一行是否匹配)
n~m从第n行开始,每次增加m行
n,m!表示与前面的模式取反,即除去n到m行的所有行

注:Linux命令行中,! 在双引号 “” 中会被解释为历史命令,所以应该改为单引号’’

4. sed操作命令

常用命令含义
a\在匹配行后面添加一行内容,可使用\n转义添加多行
i\在匹配行前面添加一行内容,可使用\n转义添加多行
c\替换匹配行内容,可使用\n转义添加多行
d删除匹配行,并启动下一轮循环
s替换匹配字符
p打印匹配行
=打印匹配行行号
w保存模式匹配的行至指定文件
r读取指定文件的文本至匹配的行后
{=;p}打印匹配行及行号;多个操作可以使用 {} 括起来,各个操作间用 ; 隔开

5. sed用法示例

  • 打印显示
mxwang@mxwang:~$ cat test.txt
Hello World!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed "2p" test.txt   # 打印第二行;sed默认打印所有行,则第二行会打印两遍
Hello World!
Hello Linux! Hello Linux!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed -n "1,2p" test.txt   # 只打印第1,2行;-n 只打印所选行
Hello World!
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n "/Python/p" test.txt   # 打印匹配Python的行
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed -n "/World/,/Linux/{=;p}" test.txt   # 打印匹配World或Linux的行号及内容
1
Hello World!
2
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n "/World/,2p" test.txt   # 打印匹配World的行到第2行
Hello World!
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n "/Hello/,2p" test.txt   # 打印匹配Hello的行到第2行,匹配Hello所有行将会被打印
Hello World!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed -n "1,/Python/p" test.txt   # 打印第一行到匹配Python的行
Hello World!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed -n "1,/Hello/p" test.txt   # 打印第一行到匹配Hello的行,从第二行检测是否匹配Hello
Hello World!
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n '/Python/!p' test.txt   # 打印不能匹配Python的行
Hello World!
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n '1,2!p' test.txt   # 打印第1-2之外的行
Hello Python! Hello Python! Hello Python!
  • 与正则表达式结合的打印显示
mxwang@mxwang:~$ cat test.txt
#!/bin/bash/
echo "OK"
var=`expr 1 + 1`
echo $var

echo "finish"
mxwang@mxwang:~$ sed -n '/^#/!p' test.txt   # 打印不以#开头的行
echo "OK"
var=`expr 1 + 1`
echo $var

echo "finish"
mxwang@mxwang:~$ sed -n '/^#/!{/^$/!p}' test.txt   #打印不以#开头中的非空行
echo "OK"
var=`expr 1 + 1`
echo $var
echo "finish"
mxwang@mxwang:~$ sed -e "/^#/d" -e "/^$/d" test.txt   # 删除以#开头的行和空行
echo "OK"
var=`expr 1 + 1`
echo $var
echo "finish"
  • 对文本内容的修改
mxwang@mxwang:~$ cat test.txt 
hello world
hello python
i love you
are you ok
who are you
mxwang@mxwang:~$ sed "/hello/s/^/hi /" test.txt   # 在匹配行开头添加hi
hi hello world
hi hello python
i love you
are you ok
who are you
mxwang@mxwang:~$ sed "/hello/s/$/ hi/" test.txt   # 在匹配行结尾添加hi
hello world hi
hello python hi
i love you
are you ok
who are you
mxwang@mxwang:~$ sed "s/love/do &/" test.txt   # 在love前面添加do
hello world
hello python
i do love you
are you ok
who are you
mxwang@mxwang:~$ sed "s/love/& do/" test.txt   # 在love后面添加do
hello world
hello python
i love do you
are you ok
who are you
mxwang@mxwang:~$ sed "/python/i hello linux" test.txt   # 在匹配行前面加一行hello linux
hello world
hello linux
hello python
i love you
are you ok
who are you
mxwang@mxwang:~$ sed "/python/i\hello linux" test.txt   # 在匹配行前面加一行hello linux
hello world
hello linux
hello python
i love you
are you ok
who are you在匹配行前面加一行hello linux
mxwang@mxwang:~$ sed "/python/a\hello linux" test.txt   # 在匹配行后面加一行hello linux
hello world
hello python
hello linux
i love you
are you ok
who are you
mxwang@mxwang:~$ sed "/python/a\hello linux\nhello hello" test.txt   #在匹配行使用\n转义添加多行
hello world
hello python
hello linux
hello hello
i love you
are you ok
who are you

四、awk用法介绍

awk是它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首字母缩写,可以把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理,是一个强大的文本分析工具。

1. 命令格式

awk [-F field-separator] 'commands' filename   # 命令行方式
awk [-F|-f|-v] 'BEGIN{} /pattern/{command1; command2} END{}' filename   # shell脚本方式
awk -f scriptfile filename   # 调用命令文件

2. 常用选项

-F: 指定分隔符
-F '[:#/]': 可定义多个分隔符,例如 : # /
-f: 调用脚本
-v: 定义变量 var=value
'': 引用代码块
BEGIN: 在对每一行文件处理前初始化代码,主要是引用全局变量,设置FS分隔符等
//: 匹配模式
{}: 命令代码块,多条命令用 ; 分割开 
END: 在对每一行处理结束后再执行代码,主要是最终计算或输出信息

3. 内置变量

变量含义
$0表示整个当前行
$1表示第1个字段,字段间由FS分隔
$n表示第n个字段
FS字段分隔符,默认是任何空格
NF一条记录的字段数量
NR已经读出的记录数量,也就是行号,从1开始,多个文件累计计数
FNR等于NR,但多个文件分别计数,均从1开始
RS记录分隔符,默认是一个换行符
OFS输出字段分隔符,默认为空格,可用指定的符号代替
ORS输出记录分隔符,默认是一个换行符,可用指定的符号代替
ARGC命令行参数的个数
ARGV数组,保存的是命令行所给定的各参数,查看参数

4. 特殊要点

特殊要点含义
~匹配,与 == 相比不是精确比较
!~不匹配,与 != 相比不是精确比较
==等于,精确比较
!=不等于,精确比较
&&逻辑与
||逻辑或

5. awk用法示例

  • 基本用法
mxwang@mxwang:~$ cat test.txt
hello:world:linux:python
it:is:a:dog
i:love:you
yes:no
mxwang@mxwang:~$ awk -F ":" '{print $1}' test.txt   # :分隔符,打印第1字段
hello
it
i
yes
mxwang@mxwang:~$ awk -F ":" '{print $1 $2}' test.txt   # 打印第1,2字段,没有分隔
helloworld
itis
ilove
yesno
mxwang@mxwang:~$ awk -F ":" '{print $1,$2}' test.txt   # 打印第1,2字段,自动空格分隔
hello world
it is
i love
yes no
mxwang@mxwang:~$ awk -F ":" '{print $1 " " $2}' test.txt   # 打印第1,2字段,手动空格分隔
hello world
it is
i love
yes no
mxwang@mxwang:~$ awk -F ":" '{print NF}' test.txt   # 打印每行的字段数量
4
4
3
2
mxwang@mxwang:~$ awk -F ":" '{print $(NF-1)}' test.txt   # 打印倒数第二个字段
linux
a
love
yes
mxwang@mxwang:~$ awk -F ":" 'NF==4{print}' test.txt   # 打印字段等4的行 
hello:world:linux:python
it:is:a:dog
mxwang@mxwang:~$ awk -F ":" 'NF>2{print $0}' test.txt   # 打印字段大于2的行
hello:world:linux:python
it:is:a:dog
i:love:you
  • 匹配字符
mxwang@mxwang:~$ cat test.txt
hello:world:linux:python
it:is:a:dog
i:love:you
yes:no
mxwang@mxwang:~$ awk '/linux/' test.txt   # 打印匹配linux的行
hello:world:linux:python
mxwang@mxwang:~$ awk '/linux/{print}' test.txt   # 打印匹配linux的行
hello:world:linux:python
mxwang@mxwang:~$ awk '/linux|is/{print}' test.txt   # 打印匹配linux或is的行
hello:world:linux:python
it:is:a:dog
mxwang@mxwang:~$ awk '!/linux|is/{print}' test.txt   # 打印不匹配linux且is的行
i:love:you
yes:no
mxwang@mxwang:~$ awk '/linux/,/is/{print}' test.txt   # 打印匹配linux或is的行
hello:world:linux:python
it:is:a:dog
mxwang@mxwang:~$ awk '!/linux/,/is/{print}' test.txt   # 打印不匹配linux或匹配is的行
it:is:a:dog
i:love:you
yes:no
mxwang@mxwang:~$ awk -F ":" '$1~/hello/{print $1}' test.txt   # 打印第1字段匹配hello的第1字段
hello
mxwang@mxwang:~$ awk -F ":" '{if($1~/hello/)print $1}' test.txt   # 打印第1字段匹配hello的第1字段
hello
mxwang@mxwang:~$ awk -F ":" '$1!~/hello|it/{print}' test.txt   # 打印第1字段不匹配hello且it的行
i:love:you
yes:no
  • 条件表达式
mxwang@mxwang:~$ cat test.txt
1 10 100
10 100 1000
100 10 1
awk '{if($2>10) print $2}' test.txt   # 缩写
100
awk '{if($2>10) {print $2}}' test.txt   # 全写
100
awk '{if($2>100) {print $2} else {print}}' test.txt   # if else
1 10 100
10 100 1000
100 10 1
awk '{$1>10 && $2>=10?x="yes":x="no";print x,$0}' test.txt   # 条件表达式(三目表达式);条件成立执行?后面,不成立执行:后面
no 1 10 100
no 10 100 1000
yes 100 10 1
mxwang@mxwang:~$ awk '{print($1>10 && $2>=10?"yes":"no")}' test.txt
no
no
yes
  • 格式输出

语法:printf “FORMAT”, item1,item2

FORMAT 中需要分别为后面每个item 指定格式符

格式符含义
\n换行符,默认不换行
%c显示字符的ASCII码
%d, %i显示十进制整数
%e, %E显示科学计数法值
%f, %3.2f显示浮点数,%5.2f表示共5位数,含两位小数,不够用空格补上
%g, %G科学计数法或浮点数显示数值
%s, %3s显示字符串,%3s表示最少3个字符,不够用空格补上,超过3个将继续显示
%u无符号整数
%%显示%自身
-, %-6s左对齐,默认右对齐,%-6s表示左对齐,最少6个字符,不够用空格补上,超过6个将继续显示
+, %+d显示数值的正负符号
mxwang@mxwang:~$ cat test.txt
name height weight
long 172.1 56
xing 168 52.3
zhang 182 82.1 
mxwang@mxwang:~$ awk 'NR==1{printf "%-10s %-10s %-10s\n",$1,$2,$3};NR!=1{printf "%-10s %-10.2f %-10.2f\n",$1,$2,$3}' test.txt
name       height     weight    
long       172.10     56.00     
xing       168.00     52.30     
zhang      182.00     82.10 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值