Linux中sed和awk命令比较实例

原文地址:http://blog.geekcome.com/archives/232

sed的工作原理

先读入一行,将读入的数据放入pattern space,执行编辑命令,处理完毕后把pattern space的内容打印出来,后面打印曾经去掉的回车符。

把pattern space的内容给hold space,然后把pattern space置空。

  • 设置每行之后有且只有一行空行

sed实现:

1 sed -i '/^$/d;G' 123.txt

命令解析:

-i表示直接在本文件修改

d表示直接删除前面匹配的内容

;分号表示如果遇到空行,则执行删除命令,而不会进一步执行G命令,直接进行下一行处理。

G命令的含义是获取缓冲区的内容追加到文本的后面。

awk实现:

1 awk '!/^$/{printf("%s\n\n",$0)}' 123.txt

命令解析:

awk无法直接修改源文件(也不推荐直接修改源文件,最好使用重定向,避免出错)

匹配到非空行,然后输出两个回车,就相当于一个空行。

  • 删除文件中所有的空行

直接将上面的命令去掉分号和G即可。

sed实现:

1 sed  '/^$/d' 123.txt

awk实现:

1 awk '!/^$/{printf("%s",$0)}' 123.txt
  • 删除所有的偶数行:

sed实现:

1 sed 'n;d' 123.txt

命令解析:

n表示读取下一行,并用下一个命令来处理对应的行。

awk实现:

1 awk  'NR%2!=0{printf("%s\n",$0)}' 123.txt

命令解析:

NR表示awk开始读取文件后所读取的行号。

  • 在匹配行前加空行

sed实现:

1 sed '/Java/{x;p;x}' 123.txt

命令解析:

x表示交换pattern和hold space

p表示打印pattern space

(sed ‘/Java/G’ 123.txt)在匹配行后加空行

awk实现:

1 awk '{if(/Java/) printf("\n%s\n",$0);else printf("%s\n",$0)}' 123.txt
  •  输出行号,并在行号和内容直接加“:”

sed实现:

1 sed 123.txt | sed 'N;s/\n/:/'

命令解析:

N:追加下一个输入行到模式空间后面并在后面添加回车符

=:输入内容

awk实现:

1 awk '{printf("%d:%s\n",NR,$0)}' 123.txt
  • 上面的例子,忽略空行,只对非空行编号

sed实现:

1 sed '/./=' 123.txt | sed '/./N;s/\n/:/'

/./表示只匹配第一个字符不是回车的行,然后如同上面的例子。

awk实现:

1 awk '{if(/./) printf("%d:%s\n",NR,$0);else print $0}' 123.txt
  •  替换指定的字符串并只打印该行

sed实现:

1 sed -n 's/re/string/'p 123.txt

-n表示sed是静默方式执行

p表示要打印pattern space的内容

awk实现:

1 awk ‘gsub(re,string) print $0’ 123.txt

gsub(r,s,t)在字符串t中用字符串s和正则表达式r匹配的所有字符串。返回值是替换的个数。如果没有给出t,默认是$0

  • 每隔5行插入空行

sed实现:

sed ‘n;n;n;n;G’ 123.txt

命令n表示读取下一行数据到pattern space,上面的例子就是读取了五行数据到pattern space,然后使用下一个命令处理数据。

命令G表示把hold space的内容追加到pattern space后面。此时hold space的内容是空。

awk实现:

awk ‘{if(NR%5!=0) print $0;else printf(“%s\n\n”,$0)}’ 123.txt

  • 倒置所有的行

sed实现:

sed ’1!G;h;$!d’ 123.txt

命令解析:

第一行的时候

1!G:在处理第一行的时候不把缓冲内容添加到 当前处理行的末尾(因为你处理第一行的时候,缓冲还为空呢)
h:这个时候把第一行的内容(1)放到缓冲区
$!d:因为不是最后一行,所以删除,不打印出来
第二行的时候
1!G:此时1!G成立,把上一次保存的缓冲区内容(1)放到当前行(2)的末尾,第二行变成了(21)
h:这个时候把第二行的内容(21)放到缓冲区
$!d:因为不是最后一行,所以删除,不打印出来
第三行的时候
1!G:因为是第三行,所以1!G成立,则把上一次(第二行)保存的缓冲区内容(21)放到当前行(3)的末尾,第二行变成了(321)
h:这个时候把第三行的内容(321)放到缓冲区
$!d:因为不是最后一行,所以删除,不打印出来
这样直到处理到最后一行的时候:
1!G:此时1!G成立,把上(n-1)一次保存的缓冲区内容([n-1]…321)放到当前行(n)的末尾,该行变成了(n…321)
h:这个时候把第n行的内容(n…321)放到缓冲区
$!d:因为是最后一行,所以不删除,打印出第六行内容 n[n-1]…321

awk实现:

awk ‘{A[i++]=$0} END {for(j=i-1;j>=0;–j) print A[j]}’ 123.txt

命令解析:

BEGIN和END
在awk 中两个特别的表达式,BEGIN和END,这两者都可用于pattern中,提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。任何在BEGIN之后列出的操作(在{}内)将在awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。

你可能感兴趣的:(技术手册)