欢迎来到魔幻小生的博客

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 将输出中的匹配项设置为自动颜色显示

image

使用正则表达式

# 查找 /etc/group 文件中包含 shiyanlou 的行
grep shiyanlou /etc/group

image

# 匹配以'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*'

image

# grep默认是区分大小写的,这里将匹配所有的小写字母
echo '1234\nabcd' | grep '[a-z]'
# 将匹配所有的数字
echo '1234\nabcd' | grep '[0-9]'

image

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

image

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'

image

# 将输入文本中"shiyanlou" 全局替换为"hehe",并只打印替换的那一行,注意这里不能省略最后的"p"命令
sed -n 's/shiyanlou/hehe/gp' passwd
# 删除第30行
sed -i '30d' passwd
posted @ 2023-05-22 22:35  魔幻小生  阅读(149)  评论(0编辑  收藏  举报