【Linux shell】grep,sed,awk介绍

今天要讲的东西是文件的格式化处理,说实话我感觉这个就是Linux比Windows要强大的地方。

Linux中的许多文件,许多命令的输出,都是高度格式化的。在了解了相应的内容之后,我们就能通过一些命令,讲我们想要的内容提取出来,下面就要介绍这么几个命令:

命令 作用
grep 查询对应字符串所在的行
sed 格式化标准输出流
awk 处理field

一. grep命令

grep命令是用来查找相应的字符串内容的,是一个不需要加任何参数就可以使用正则表达式的管道命令

grep pattern

一个最常用的参数是-v,通过这个参数我们可以进行反选

grep -v pattern

(使用grep的一个best practice就是删除所有的空行,你可以自己试一试)

如果想要查看上下文,可以指定-A,-B,-C参数。

其中,-A + 数字是用来查看当前行之前的几行内容,-B刚好相反。-C是用来查看之前几行和之后几行的内容。

grep -A/B/C num pattern

最后关于grep重要的一点,就是他有两种风格,一种是BRE风格,使用的是基本正则表达式,另一种是ERE风格,使用的是扩展正则表达式。两者的区域在于ERE风格添加了|{}等符号的特殊含义。如果你要使用扩展正则表达式的话,可以使用:

# 虽然有了ERE,我更加推荐直接使用egrep
egrep
grep -E

二. sed命令

sed命令也是一个管道命令,他的作用则是对标准输出做一个格式化的处理。他可以对标准输出做一个新增,插入,删除,替换等的操作。

(1). 新增行

新增行有两个参数:-i, -a。其中-i是在相应行之前插入, -a是在相应行之后插入内容。

# 注意到sed的用法和grep完全不同
# 下面以0作为占位符,展示了sed插入行的做法
sed "0a content"
sed "0i content"

(2). 删除行

# 下面展示两种模式
# 删除指定的一行(以数字0作为行号的占位符)
sed "0d content"
# 删除指定区间的所有行(以数字1和2作为行号的占位符)
sed "1,2d content"

(3). 替换行

替换航和删除行的做法如出一辙,只不过是把function从d改成了c:

sed "0c content"
sed "1,2c content"

(4). 替换部分内容

注意与替换行相区别,这里的替换,做的就是vim里面的替换工作,function也是vim里面的s:

sed "s/要被替换的内容/替换的内容/g"

比如我要把用#开头的注释行全部删除,我的做法就是:

# 这里用到了一个小技巧,讲被替换的内容用什么都没有的东西代替,起到了删除内容的作用
sed "s/^#.*$//g"

三. awk命令

awk的作用就是对输出内容中的各个字段做一个处理,下面简单地介绍一下它的概念:

(1). 形式

awk '条件类型{操作1} 条件类型{操作2}...'

注意awk的用法和sed的相同之处在于——都要用“”把后续的操作包起来

区别则是在“”中,awk又可以包含各种不同的条件类型和子操作,子操作又用{}包起来

(2). 内置变量

awk是有内置变量的,这就是为什么awk能用来处理字段的最重要的原因。

用来表示各个字段的变量有:

  1. $0: 这个是一个特殊的变量,用来指代整一行的数据
  2. $1, $2, ...: 这些变量分别来指代第一个字段,第二个字段的内容。

还有一些特殊的变量,如:

  1. NF:每一行拥有的字段总数。
  2. NR:目前awk所处理的是第几行的数据。
  3. FS:目前的分隔字符,默认是空格键。

这些内置的变量既可以用在条件类型中,也可以用在操作中。

(3). 条件类型

说到条件就要提到布尔类型,你还别说,awk真的有一套和C++一致的布尔类型运算符。这里就不做列举了。

awk还有一些关键字也可以用来做条件类型,比如BEGIN和END,这两个分别代表了处理第一行和处理最后一行

(4). 操作

awk内置一套操作。你可以通过man文档来进行查看。基本上就是按照shell script的写法来写的。

你甚至可以不适用条件类型,直接在{}里面写带逻辑的script:

# 这里直接用了命令,由此可以看出和写shell还是差不太多的
# printf还是和C++差不多,需要自己补上换行号
awk '{if (NR==1) printf("Hello World\n")}'

(5). 内置函数

个人认为awk的精髓是内置的函数,awk内置了许多函数,最著名的就是print函数,他能把内容打印到标准输出流中。

# 这里print的使用方式又像python一样
# 自动换行,可以任意拼接你想输出的东西
# 注意引号之间的匹配问题
awk '{print %1 "==" %2}'

awk还有处理字符串的函数,如substr或者split等,这个可以自行查阅文档。

下面考虑这个问题:

这里给出两种思路,一种是利用index求索引然后substr求子串:

awk '{print substr($1, index($1, "/") + 1) "==" $2}'

 还有一种就是利用split得到分割后数组,然后取出相应元素:

awk '{split($1, str_arr, "/")}{print str_arr[2] "==" $2}'
发布了137 篇原创文章 · 获赞 19 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43338695/article/details/103845369