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
Hello World!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ grep -c Hello test.txt
3
mxwang@mxwang:~$ grep -in hello test.txt
1:Hello World!
2:Hello Linux! Hello Linux!
3:Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ grep -e Linux -e Python test.txt
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
OK
OOOK
mxwang@mxwang:~$ grep "O.*K" test.txt
OK
OOOK
mxwang@mxwang:~$ grep "O\?K" test.txt
K
OK
OOOK
mxwang@mxwang:~$ grep -E "O+K" test.txt
OK
OOOK
mxwang@mxwang:~$ egrep "O{1,3}K" test.txt
OK
OOOK
mxwang@mxwang:~$ grep "\<O.*K\>" test.txt
OK
OOOK
mxwang@mxwang:~$ grep "\<\(O\).\1K\>" test.txt
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. 文本定位命令
定位命令 含义 不给定位置,表示对全文进行处理 n n为行号,对指定行进行处理 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
Hello World!
Hello Linux! Hello Linux!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed -n "1,2p" test.txt
Hello World!
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n "/Python/p" test.txt
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed -n "/World/,/Linux/{=;p}" test.txt
1
Hello World!
2
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n "/World/,2p" test.txt
Hello World!
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n "/Hello/,2p" test.txt
Hello World!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed -n "1,/Python/p" test.txt
Hello World!
Hello Linux! Hello Linux!
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ sed -n "1,/Hello/p" test.txt
Hello World!
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n '/Python/!p' test.txt
Hello World!
Hello Linux! Hello Linux!
mxwang@mxwang:~$ sed -n '1,2!p' test.txt
Hello Python! Hello Python! Hello Python!
mxwang@mxwang:~$ cat 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 -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 hello world
hi hello python
i love you
are you ok
who are you
mxwang@mxwang:~$ sed "/hello/s/$/ hi/" test.txt
hello world hi
hello python hi
i love you
are you ok
who are you
mxwang@mxwang:~$ sed "s/love/do &/" test.txt
hello world
hello python
i do love you
are you ok
who are you
mxwang@mxwang:~$ sed "s/love/& do/" test.txt
hello world
hello python
i love do you
are you ok
who are you
mxwang@mxwang:~$ sed "/python/i hello linux" test.txt
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 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 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
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
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
hello
it
i
yes
mxwang@mxwang:~$ awk -F ":" '{print $1 $2 }' test.txt
helloworld
itis
ilove
yesno
mxwang@mxwang:~$ awk -F ":" '{print $1 ,$2 }' test.txt
hello world
it is
i love
yes no
mxwang@mxwang:~$ awk -F ":" '{print $1 " " $2 }' test.txt
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
hello:world:linux:python
it:is:a:dog
mxwang@mxwang:~$ awk -F ":" 'NF>2{print $0 }' test.txt
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
hello:world:linux:python
mxwang@mxwang:~$ awk '/linux/{print}' test.txt
hello:world:linux:python
mxwang@mxwang:~$ awk '/linux|is/{print}' test.txt
hello:world:linux:python
it:is:a:dog
mxwang@mxwang:~$ awk '!/linux|is/{print}' test.txt
i:love:you
yes:no
mxwang@mxwang:~$ awk '/linux/,/is/{print}' test.txt
hello:world:linux:python
it:is:a:dog
mxwang@mxwang:~$ awk '!/linux/,/is/{print}' test.txt
it:is:a:dog
i:love:you
yes:no
mxwang@mxwang:~$ awk -F ":" '$1 ~/hello/{print $1 }' test.txt
hello
mxwang@mxwang:~$ awk -F ":" '{if($1 ~/hello/)print $1 }' test.txt
hello
mxwang@mxwang:~$ awk -F ":" '$1! ~/hello|it/{print}' test.txt
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
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