博客 2016-08-30

简介:

sed 是古老的文本处理工具,如果熟练掌握,也是利器


实例:

需求:下面中的WHERE 与SET 互换


文件1.txt的内容是这样的:

### update test.student
### WHERE
### @1=1 /* int meta=0 */
### @2='a' /* int meta=0 */
### @3=1 /* int meta=0 */
### @4='56' /* int meta=0 */
### SET
### @1=1  /* int meta=0 */
### @2='a' /* int meta=0 */
### @3=1 /* int meta=0 */
### @4='failture' /* int meta=0 */
### update test.student


方法:

sed '/WHERE/{:a;N;/SET/!ba;s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}'  1.txt


解释:


:a  做个label,方便后面跳转到这里
N   下一行,并追加到pattern 模式(暂存区)的后面
/SET/!ba  匹配到SET  就不跳转到a 标签。 否则继续追加行
不跳转,就会接着执行后面的命令:s 替换了
这样暂存区的内容就是:
### WHERE\n
### @1=1 /* int meta=0 */\n
### @2='a' /* int meta=0 */\n
### @3=1 /* int meta=0 */\n
### @4='56' /* int meta=0 */\n
### SET
*是最大匹配原则
1= ### WHERE    
2=
### @1=1 /* int meta=0 */\n
### @2='a' /* int meta=0 */\n
### @3=1 /* int meta=0 */\n
### @4='56' /* int meta=0 */
3=  ### SET


扩展:

想知道原理,看下这个:(倒序排列一个文件的工作流)

sed ‘1!G;h;$!d’ file

sed.png


http://blog.itpub.net/27181165/viewspace-1276719/


常用:

Sed Commands

: label   # comment      {....} Block

= - print line number      a \ - Append     b label - Branch

c \ - change            d and D - Delete    g and G - Get

h and H - Hold           i \ - Insert       l - Look

n and N - Next           p and P - Print       q - Quit

r filename - Read File      s/..../..../ - Substitute  t label - Test

w filename - Write Filename  x - eXchange         y/..../..../ - Transform

Sed Pattern Flags

/g - Global  /1 - first   /2 - second

/I - Ignore Case

/p - Print

/w filename - Write Filename


$ cat file  
aa  
88  
bb  
88  
88  
cc  
88  
88

#替换第一个88为--  

sed ':a;N;$!ba;s/88/--/' file  

sed ':a;N;$!ba;s/88/--/1' file  

#替换第n个88为--  

sed ':a;N;$!ba;s/88/--/n' file  

  

sed -n1,10p   Print first 10 lines

sed -n11,$!p   Print first 10 lines


mysql  的sql目录下Makefile中


.yy.cc:
        $(YACCCOMPILE) $<
        if test -f y.tab.h; then \
          to=`echo "$*_H" | sed \
                -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
                -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \
          sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \    ##与/^#/ 匹配,就不执行-e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" 的命令
            y.tab.h >$*.ht; \
          rm -f y.tab.h; \
          if cmp -s $*.ht $*.h; then \
            rm -f $*.ht ;\
          else \
            mv $*.ht $*.h; \
          fi; \
        fi
        if test -f y.output; then \
          mv y.output $*.output; \
        fi
        sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@
        rm -f y.tab.c

更多实例

http://blog.chinaunix.net/uid-10540984-id-2983419.html

http://www.grymoire.com/Unix/Sed.html


不足:


sed 处理分段的文本,要求比较苛刻,比如要么以一行做分割,要么有专有标志,

现在流行的json 格式是比较完美的,结合python 等编程,要比sed 好很多