文本处理三剑客之sed命令详解

sed是流编辑器,可以对文本进行逐行判断并编辑的一种非常强大的文本处理工具

工作原理:

1.读取一行到模式空间(pattern space)

2.从指定的操作指令集中取出第一个指令,判断是否匹配所要的模式

3.不匹配就忽略后续的编辑指令,直接回到第2步读取下一条指令,以此类推,直到所有指令执行完毕

4.输出缓存在模式空间的内容,有-n选项则抑制这项输出,回到第一步继续读取下一行的内容,重复上述操作

5.直到所有行都处理完毕,结束

注:所有的处理都是对模式空间里的内容进行处理

使用格式:sed [option]... {Script} [FILE]...(其中Script包括地址跟编辑命令)

常用选项:

-n  抑制模式空间的行输出

-e  多项编辑命令一次性执行

-r  支持扩展的正则表达式

-f  file 将操作命令集写在文件中,使用-f调用该文件

-i  直接修改源文件

-i.bak 直接修改源文件的同时生成备份文件

地址:

  空地址:对全文进行处理

  单地址

    n 行号,对第n行进行处理

    /pattern/ 被正则表达式匹配到的行

  地址对:

    n,m  第n行到第m行

    n,+m   从第n行到向下m行

    n,/pattern/  从第n行到正则表达式匹配到的行

    /pattern1/,/pattern2/  从pattern1匹配到的行到pattern2匹配到的行

    $  最后一行

  步进地址表示法:

    n~m 从第n行开始,每隔m行处理一行,例,处理所有奇数行:1~2;所有偶数行:2~2

编辑命令:

模式空间命令:

  d:delete,删除模式空间的内容

  p:print,将模式空间里的内容打印至屏幕

  =:输出行号

  n:next,读取下一行

  l:list,输出行控制符,类似$,\t等

  [line-address]c\string:change,改变指定行的内容为string,只支持单行处理

  [line-address]a\STRING:append,在指定行下一行追加内容,只支持单行处理

  [line-address]i\STRING:insert,在指定行上一行追加内容,只支持单行处理

  s/RegExp/REPLACE/g:search,搜索与替换,"/"可以换成其他符号:#@%…支持多行处理

  在s///中使用分组及后向引用   eg: sed -r 's/i love (\S+) and (\S+)/\1 love \2/' /tmp/test

  y/abc/xyz/:转换字符,a转成x,b转成y,c转成y,逐一对应转换   

  [line-address]r file:read,将文件 file 的内容读取到指定行中

  w file:write,保存内容至文件 file 中

  [line-address]q : quit,读取到匹配行之后退出

  N:将下一行读至模式空间,用\n连接上一行,若其后再无操作,则等价于跳过下一行

  P:输出上一行的内容

  D:删除上一行的内容

保持空间命令:

  H/h:hold,将模式空间内容复制(h),通过\n追加(H)到保持空间

  G/g: get,将保持空间内容复制(g),通过\n追加(G)到模式空间

  x:exchange,将保持空间内容和模式空间内容交换

例子:

1.使用n或p打印奇数行或偶数行(列出4种方法)

 

1 sed -n 'p;n' test.txt #奇数行
2 sed -n 'n;p' test.txt #偶数行
3 sed -n '1~2p' test.txt #奇数行
4 sed -n '2~2p' test.txt #偶数行

 

2.对于包含test到west之间的行,每行加上字符串'aaa bbb'

  sed '/test/,/west/s/$/aaa bbb/' file 

3. 查找包含line1的行到包含line2的行之间的所有aa bbb替换成AA BBB

  sed '/line1/,/line2/s/aa bbb/AA BBB/' test.sh 

4.显示第一次匹配到的3到最后一行输出

  sed -n '/3/,$p' test.sh 

5.逆序显示文本内容

1 sed '1!G;h;$!d' test
2 sed -n  '1!G;h;$p' test

6.删除原有的所有空白行,而后为所有的非空白行后添加一个空白行

  sed '/^$/d;G' /etc/passwd 

7.将'yes'替换成'no',并且只在行中未出现字串'hello'的情况下替换

  sed '/hello/ !s/yes/no/g' file 

8.将每行的字符逆序显示

 sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//' file 

这题较难,给一个流程:

PATT:abc$
HOLD:$
COMM:/\n/ !G
PATT:abc\n$
HOLD:$
COMM:s/\(.\)\(.*\n\)/&\2\1/
PATT:abc\nbc\na$
HOLD:$
COMM:// D
PATT:bc\na$
HOLD:$
COMM:/\n/ !G
PATT:bc\na$
HOLD:$
COMM:s/\(.\)\(.*\n\)/&\2\1/
PATT:bc\nc\nba$
HOLD:$
COMM:// D
PATT:c\nba$
HOLD:$
COMM:/\n/ !G
PATT:c\nba$
HOLD:$
COMM:s/\(.\)\(.*\n\)/&\2\1/
PATT:c\n\ncba$
HOLD:$
COMM:// D
PATT:\ncba$
HOLD:$
COMM:/\n/ !G
PATT:\ncba$
HOLD:$
COMM:s/\(.\)\(.*\n\)/&\2\1/
PATT:\ncba$
HOLD:$
COMM:// D
PATT:\ncba$
HOLD:$
COMM:s/.//
PATT:cba$
HOLD:$
cba

9.将数字'1234567'显示为1,234,567

 echo "1234567" | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta' 

 

posted @ 2018-11-26 21:58  hwff  阅读(479)  评论(0编辑  收藏  举报