Linux三剑客awk、grep、sed详解

一、前言linux 有很多工具可以做文本处理,例如:sort, cut, split, join, paste, comm, uniq, column, rev, tac, tr, nl, pr, head, tail.....,学习 linux 文本处理的懒惰方式(不是最好的方法)可能是:只学习grep,sed和awk 。使用这三个工具,你可以解决近 99% linux 系统的文本处理问题,而不需要记住上面不同的命令和参数 。:)
而且,如果你已经学会并使用了三者,你就会知道其中的差异 。实际上,这里的差异意味着哪个工具擅长解决什么样的问题 。
一种更懒惰的方式可能是学习脚本语言(Python,perl或ruby)并使用它进行每个文本处理 。
二、概述awk、grep、sed 是 linux 操作文本的三大利器,也是必须掌握的 linux 命令之一 。三者的功能都是处理文本,但侧重点各不相同,其中属 awk 功能最强大,但也最复杂 。grep 更适合单纯地查找或匹配文本,sed 更适合编辑匹配到的文本,awk 更适合格式化文本,对文本进行较复杂格式处理 。
简单概括:

  • grep:数据查找定位
  • awk:数据切片
  • sed:数据修改
三、grep = global regular expression print用最简单术语来说,grep(全局正则表达式打印)--命令用于查找文件里符合条件的字符串 。从文件的第一行开始,grep 将一行复制到 buffer 中,将其与搜索字符串进行比较,如果比较通过,则将该行打印到屏幕上 。grep将重复这个过程,直到文件搜索所有行 。
注意这里没有进程执行 grep 存储行、更改行或仅搜索部分行 。
1、示例数据文件请将以下数据剪切粘贴到一个名为 “sampler.log” 的文件中:
bootbookboozemachinebootsbungiebarkaardvarkbroken$tuffrobots2、一个简单例子grep 最简单的例子是:
grep "boo" sampler.log 在本例中,grep 将遍历文件 “sampler.log” 的每一行,并打印出其中的每一行 包含单词“boo”:
bootbookboozeboots但是如果你操作的是大型文件,就会出现这种情况:如果这些行标识了文件中的哪一行,它们是什么,可能对你更有用,如果需要在编辑器中打开文件,那么可以更容易地跟踪特定字符串做一些改变 。这时候可以通过添加 -n 参数来实现:
grep -n "boo" sampler.log这产生了一个更有用的结果,解释了哪些行与搜索字符串匹配:
1:boot2:book3:booze5:boots另一个有趣的参数是 -v,它会打印出相反的结果 。换句话说,grep 将打印所有与搜索字符串不匹配的行,而不是打印与之匹配的行 。
在下列情况下,grep 将打印不包含字符串 “boo” 的每一行,并显示行号,如上一个例子所示
grep -vn "boo" sampler.log 4:machine6:bungie7:bark8:aardvark9:broken$tuff10:robotsc 选项告诉 grep 抑制匹配行的打印,只显示匹配行的数量,匹配查询的行 。
例如,下面将打印数字4,因为有4个在 sampler.log 中出现 “boo” 。
grep -c "boo" sampler.log 4l 选项只打印查询中具有与搜索匹配行的文件的文件名字符串 。如果你想在多个文件中搜索相同的字符串,这将非常有用 。像这样:
grep -l "boo" *对于搜索非代码文件,一个更有用的选项是 -i,忽略大小写 。这个选项将处理在匹配搜索字符串时,大小写相等 。在下面的例子中,即使搜索字符串是大写的,包含“boo”的行也会被打印出来 。
grep -i "BOO" sampler.log bootbookboozebootsx 选项只精确匹配 。换句话说,以下命令搜索没有结果,因为没有一行只包含"boo"
grep -x "boo" sampler.log 最后,-A 允许你指定额外的上下文件行,这样就得到了搜索字符串额外行,例如
grep -A2 "mach" sampler.logmachinebootsbungie3、正则表达式正则表达式是描述文本中复杂模式的一种紧凑方式 。有了 grep 你可以使用搜索模式( pattern )。其他工具使用正则表达式 (regexp) 以复杂的方式 。
而 grep 使用的普通字符串,实际上非常简单正则表达式 。如果您使用通配符,如 ' * ' 或 ' ? ',比如列出文件名等,你可以使用 grep 使用基本的正则表达式进行搜索 例如搜索文件以字母 e 结尾的行:
grep "e$" sampler.log boozemachinebungie如果需要更广泛的正则表达式命令,则必须使用grep -E 。例如,正则表达式命令 ? 将匹配1或0次出现 之前的字符:
grep -E "boots?" sampler.log bootboots


推荐阅读