Linux三剑客(grep/awk/sed)及正则表达式
Linux 给人的印象是黑乎乎的神秘窗口,文本操作和数据处理似乎没有 Windows 窗口界面直观方便。其实 Linux 有自己的独特的法宝,称之为三剑客:grep,awk 和 sed 。你可以用这三件法宝很方便的处理数据 : 查找,分段,修改。
正则表达式
要想对文本和数据进行操作,一定离不开正则表达式,本文首先对正则表达式进行介绍。
练习网站:https://tool.oschina.net/regex
什么是正则表达式
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为 regex、regexp 或 RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
基本语法
一个正则表达式通常被称为一个模式(pattern),为用来描述或者匹配一系列符合某个句法规则的字符串。
字符 | 描述 |
---|---|
^ | 匹配字符串的开始位置 |
$ | 匹配字符串的结束位置 |
* | 匹配前面的子表达式零次或多次,等价于{0,} |
+ | 匹配前面的子表达式一次或多次,等价于{1,} |
? | 匹配前面的子表达式零次或一次,等价于{0,1} |
{n} |
匹配确定的 n 次 |
{n,} |
至少匹配 n 次 |
{n,m} |
最少匹配 n 次且最多匹配 m 次 |
. | 匹配除\n外任何单个字符 |
[xyz] |
匹配所包含的任意字符 |
[^xyz] |
匹配未列出的任意字符 |
[a-z] |
匹配指定范围内的任意字符 |
[^a-z] |
匹配任何不在指定范围内的任意字符 |
以上是基本语法,真正使用的时候一般会与后续要介绍的grep/awk/sed结合使用。
grep 命令
grep
命令用于打印输出文本中匹配的模式串。
常用参数
参数 | 说明 |
---|---|
-b | 将二进制文件作为文本来进行匹配 |
-c | 统计以模式匹配的数目 |
-i | 忽略大小写 |
-n | 显示匹配文本所在行的行号 |
-v | 反选,输出不匹配的内容 |
-s | 递归匹配查找 |
-A n | A表示after,除了列出匹配行之外,还列出后面的n行 |
-B n | B表示before,除了列出匹配行之外,还列出前面的n行 |
--color=auto | 将输出中的匹配项设置为自动颜色显示 |
使用正则表达式
# 查找 /etc/group 文件中包含 shiyanlou 的行
grep shiyanlou /etc/group
# 匹配以'z'开头以'o'结尾的所有字符串
echo 'zero\nzo\nzoo' | grep 'z.*o'
# 匹配以'z'开头以'o'结尾,中间包含一个任意字符的字符串
echo 'zero\nzo\nzoo' | grep 'z.o'
# 匹配以'z'开头以多个'o'结尾的字符串
echo 'zero\nzo\nzoo' | grep 'zo*'
# grep默认是区分大小写的,这里将匹配所有的小写字母
echo '1234\nabcd' | grep '[a-z]'
# 将匹配所有的数字
echo '1234\nabcd' | grep '[0-9]'
awk 文本处理语言
AWK 是一种优良的文本处理工具,Linux 及 Unix 环境中现有的功能最强大的数据处理引擎之一。它允许你创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。最简单地说,AWK 是一种用于处理文本的编程语言工具。
awk 所有的操作都是基于 pattern(模式)—action(动作)对来完成的,即pattern {action}
。它将所有的动作操作用一对 {}
花括号包围起来。其中 pattern 通常是表示用于匹配输入的文本的“关系式”或“正则表达式”,action 则是表示匹配后将执行的动作。awk 处理文本的方式,是将文本分割成一些“字段”,然后再对这些字段进行处理,默认情况下,awk 以空格作为一个字段的分割符,不过这不是固定的,你可以任意指定分隔符,下面将告诉你如何做到这一点。
awk [-F fs] [-v var=value] [-f prog-file | 'program text'] [file...]
- -F:用于预先指定前面提到的字段分隔符
- -v:用于预先为awk程序指定变量
- -f:用于指定awk命令要执行的程序文件,或者在不加-f参数的情况下直接将程序语句放在这里,动作操作用一对
{}
花括号包围起来 - file...:最后为awk需要处理的文本输入,且可以同时输入多个文本文件
vi test
I like linux
www.shiyanlou.com
# 使用 awk 将文本内容打印到终端
awk '{print}' test
# 将 test 的第一行的每个字段单独显示为一行
$ awk '{
> if(NR==1){
> print $1 "\n" $2 "\n" $3
> } else {
> print}
> }' test
sed 流编辑器
sed 工具在 man 手册里面的全名为 "sed - stream editor for filtering and transforming text",意即,用于过滤和转换文本的流编辑器。
sed 命令基本格式:
sed [参数]... [执行命令] [输入文件]...
# 形如:
$ sed -i 's/sad/happy/' test # 表示将test文件中的"sad"替换为"happy"
- -n:安静模式,只打印受影响的行,默认打印输入数据的全部内容
- -e:用于在脚本中添加多个执行命令一次执行,在命令行中执行多个命令通常不需要加该参数
- -f filename:指定执行 filename 文件中的命令
- -r:使用扩展正则表达式,默认为标准正则表达式
- -i:将直接修改输入文件内容,而不是打印到标准输出设备
sed 执行命令格式:
[n1][,n2]command
[n1][~step]command
其中一些命令可以在后面加上作用范围,形如:
sed -i 's/sad/happy/g' test # g 表示全局范围
sed -i 's/sad/happy/4' test # 4 表示指定行中的第四个匹配字符串
其中 n1,n2 表示输入内容的行号,它们之间为 , 逗号则表示从 n1 到 n2 行,如果为 ~ 波浪号则表示从 n1 开始以 step 为步进的所有行;command 为执行动作,下面为一些常用动作指令:
命令 | 说明 |
---|---|
s | 行内替换 |
c | 整行替换 |
a | 插入到指定行的后面 |
i | 插入到指定行的前面 |
p | 打印指定行,通常与-n参数配合使用 |
d | 删除指定行 |
# 打印2-5行
cat passwd | sed -n '2,5p'
# 打印奇数行并显示行号
nl passwd | sed =n '1~2p'
# 将输入文本中"shiyanlou" 全局替换为"hehe",并只打印替换的那一行,注意这里不能省略最后的"p"命令
sed -n 's/shiyanlou/hehe/gp' passwd
# 删除第30行
sed -i '30d' passwd