Linux 中,我们经常会遇到对文件进行处理的需要,例如从大量日志文件中抽取目标信息进行分析等。这时就需要一款有力的工具,能够轻松实现文件信息的提取,修改。幸运的是 Linux 为我们提供了两个这样的工具。sed 和 gawk 几乎可以满足我们日常工作中99%以上的日志处理要求。
sed 编辑器 (stream editor)
从名字看出,sed 是针对文件流做处理的命令。它有如下特点:
- 一次从输入中读取一行数据
- 根据所提供的编辑器命令匹配数据
- 按照命令修改流中的数据
- 将新的数据输出到STDOUT
sed [-hnV][-e<script>][-f<script文件>][文本文件]
- -e<script>或--expression=<script> 以选项中指定的script来处理输入的文本文件。
- -f<script文件>或--file=<script文件> 以选项中指定的script文件来处理输入的文本文件。
- -n或--quiet或--silent 仅显示script处理后的结果。
- a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
- c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
- d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
- i : 插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
- p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
- s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正则表示法!
举例(文件内容替换):
echo "Hello world" | sed 's/world/dear world/'
sed 用了 s 参数,是将 原文中的 world 替换成 dear world. 所以输出是 "Hello dear world"
对于文件的修改也是如此:
图1
从图1 看出,sed 命令替换了指定的内容,值得注意的是,sed 命令并不会修改文件本身,只是将文件作为输入流,修改内容后发送到 STDOUT.文件本身并没有修改。当然,如果想修改,你可以通过STDOUT重定向实现,具体方法参看以前的文章有介绍过。值得注意的是,"sed s" 只会替换文本行中第一次匹配的内容,这点稍后会讲解。
从文件中读取命令
只需要用-f 参数指定命令文件即可,举例:
图2
图2中,将替换命令放到了 script1.sed 文件中,sed -f 指定命令文件对 data1.txt 文件内容输入流修改,并输出到终端。
gawk 程序
gawk 可以应用于日志处理,从日志文件中提取目标元素,并将其格式化为更加易读的报告。
gawk options program file
- -F fs or --field-separator fs 指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
- -v var=value or --asign var=value
- 赋值一个用户定义变量。
- -f scripfile or --file scriptfile
- 从脚本文件中读取awk命令。
- -mf nnn and -mr nnn
- 对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
数据字段变量
- $0 代表整个文本行
- $1 代表文本行中第一个字段
- ......
- $n 代表文本行中第n个字段
图3
如图3,gawk 默认字段分隔符是空白字符,所以$3表示文本行中第3个字段。
从文件中读取命令
和sed 命令相似,gawk 也可以从文件脚本中读取命令参数。
图4
如图4, script2.gawk中,打印每行文本的第一个元素,以及第六个元素。
gawk -F: 指定冒号作为元素分隔符, 格式处理采用从文件中读取,passwd作为文件输入流。所以该命令打印了系统中用户以及对应的该用户的home 路径。
BEGIN/END 用法
BEGIN常用于头部信息格式化输出,END常用于尾部信息格式化输出,直接上例子
图5
上图中,script2.gawk 中,BEING 格式化了信息头,END 在打印结束后格式化了尾部信息。
sed 替换选项
上文提过,'sed s’ 只会替换行中第一个匹配的内容,如图:
图6
如图6,'sed s' 替换data4.txt中的test 内容,结果只替换了第一次出现test的地方。有时这并不是我们想要的结果,多以sed 为我们提供了更多的选项,从而实现更多的控制。格式为:
s/pattern/replacement/flag
flag的内容可以为如下的定义
- 数字, 表明新文本将替换第几处匹配的地方
- g, 表明新文本将会替换所有匹配的文本
- p, 表明原先行的内容要打印出来
- w file, 将替换的结果输出到文件中
举例:
图7
例子比较简单,就不赘述了。
sed 修改指定行的内容
sed 命令默认会修改所有行的内容,但有时我们可能希望修改指定行的内容,所以强大的sed 命令也为我们提供了行寻址的参数。主要有两种方式:
- 数字方式寻址
- 文本模式过滤特定行
数字寻址
通过指定某一行,或者指定行数区间,来实现更改部分行内容的控制,上例子
图8
通过在 ‘s’ 前加上特定行号或者行区间,实现目标行的修改,其中行区间通过 'n, ms'的格式来实现的,其中m>n, 如果想从某一行开始到最后一行,可以通过 'n,$s' 来实现。
文本模式过滤
格式为 /pattern/command, 其中pattern 可以是正则表达式, 举例
图9
删除行
上文介绍过,删除行可以通过 ‘sed d’来实现,同样支持删除指定行的内容,格式和替换指定行内容的格式相似,直接上例子:
图10
图10 例子非常简单,不再赘述。不懂得可以私信给我。
插入内容到指定行
想插入内容到指定行,可以通过 i,a 选项来实现。
- i,插入内容到指定行的上一行,
- a,插入内容到指定行的下一行
修改行内容
和插入命令用法相似,只是命令选项换成 c。
例子比较简单,不多解释了。有疑问的小伙伴可以随时私信我。