ITPub博客

首页 > Linux操作系统 > Linux操作系统 > sed用法总结

sed用法总结

原创 Linux操作系统 作者:Aminiy 时间:2013-12-02 15:13:59 0 删除 编辑
1.sed


[root@stu93 sed]# sed -r '/\n!G;s/(.)(.*\n)/&\2\1;//D;s/.//' abc.txt 
回去查
流编辑器 stream editer,是以行为单位的处理程序


sed 流编辑器 stream editer


语法
   sed [options] 'command' in_file[s]
options 部分
-n 阻止输入行自动输出
-e
-i
-f 脚本文件
-r 支持拓展正则
command 部分
'[地址1,地址2] [函数] [参数(标记)]'

定址的方法 1.数字 2.正则
数字
  十进制数
1 单行   
1,3 范围 从第一行到第三行
2,+4 匹配行后若干行
4,~3   从第四行到下一个3的倍数行
2~3 第二行起每间隔三行的行
$ 尾行
1! 除了第一行以外的行
2.sed  -n '' /etc/passwd 阻止输入行自动显示
3.sed -n  'p' /etc/passwd
4.'cmd'
定址 函数[标记];函数
5. [root@stu93 ~]# sed  -n '1{p;p}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
[root@stu93 ~]# sed  -n '1p;3p' /etc/passwd
[root@stu93 ~]# sed -n '/^id/s/[0-6]/3/p' /etc/inittab 
id:3:initdefault:
6 [root@stu93 ~]# cat -n /etc/passwd | sed '6,~3p'倍数行
[root@stu93 ~]# cat -n /etc/passwd | sed '6,+3p'重复行
[root@stu93 ~]# cat -n /etc/passwd | sed '6~3p'间隔行
[root@stu93 ~]# cat -n /etc/passwd | sed '6p'指定行
[root@stu93 ~]# cat -n /etc/passwd | sed '6!p'除了6行
[root@stu93 ~]# cat -n /etc/passwd | sed '$p'最后一行
[root@stu93 ~]# sed -n '/root\|seker/p' /etc/passwd  含root和seker的行
[root@stu93 ~]# sed -n '/^root/,/^adm/p' /etc/passwd 以root和adm开头的行
[root@stu93 sed]# sed  '2c xyz.txt' abc.txt
aaaaaaaaaaa
xyz.txt
ccccccccccc


7. 基本正则
正则介绍


 ^ 行首
 $ 行尾
 . 除了换行符以外的任意单个字符
 * 前导字符的零个或多个
 .* 所有字符贪婪性取多不取少
 [] 字符组内的任一字符
 [^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)
 ^[^] 非字符组内的字符开头的行
 [a-z] 小写字母
 [A-Z] 大写字母
 [a-Z] 小写和大写字母
四则运算 [+ - * /]不可以 [- + * /]减号方前面就可以了
 [0-9] 数字
 \< 单词头 单词一般以空格或特殊字符做分隔,连续的字符串被当做单词
 \> 单词尾

. 匹配除换行符职位的任意单个字符,awk中可以匹配换行符
* 匹配任意一个(包括零个)在它前面的字符
[...] 匹配方括号中的任意一个字符,^为否定匹配, -表示字符的范围
^ 作为正则表达式的第一个字符,匹配行的开始。在awk中可以嵌入换行符
$ 作为正则表达式的最后一个字符,匹配行的结尾。在awk中可以嵌入换行符
\{n,m\} 匹配出现的n到m次数, \{n\}匹配出现n次。\{n,\}匹配至少出现n次
\ 转义字符
\< \>单词
sed '/正则/'
8. 扩展正则
sed -r '拓展正则'
grep -E
egrep
grep \
+ 匹配前面的正则表达式的一次出现或多次出现
? 匹配前面的正则表达式的零次出现或一次出现
| 可以匹配前面的或后面的正则表达式(替代方案)
() 对正则表达式分组
{n,m} 匹配出现的n到m次数, {n}匹配出现n次。{n,}匹配至少出现n次,大多数awk都不支持,用于POSIX egrep和POSIX awk

[root@stu93 ~]# cat 4
egg
cow
[root@stu93 ~]# sed -e 's/egg/cow/' -e 's/cow/pig/ ' 4
pig
pig

[root@stu93 ~]# sed -e 's/cow/pig/' -e 's/egg/cow/'  4
cow
pig
此时应该考虑顺序问题 可以变换下替换顺序
扩展正则 加 -r 参数 或转义
 sed -n '/roo\?/p' /etc/passwd  
 sed -rn '/roo?/p' /etc/passwd
 ? 前导字符零个或一个
 + 前导字符一个或多个
 abc|def abc或def
 a(bc|de)f abcf 或 adef
 x\{m\}   x出现m次
 x\{m,\}  x出现m次至多次(至少m次)

 x\{m,n\} x出现m次至n次


函数
增删改
 a\ 后插
 c\ 替换
 i \前插
 d 删除
这些命令每一个都要求后面加一个反斜杠用于转义第一个行尾
输入输出
 p 打印匹配的行 一般和 -n 参数连用,以屏蔽默认输出
 r 从文件中读入
 w 写入到文件中
y 字符替换(变形)
q 退出
控制流
 !  命令取反 例: 1!d 删除第一行以外的行
 {} 命令组合 命令用分号分隔 {1h;G} 可以理解为 -e 参数的另一种写法


 =  打印行号(输入行的号码,而非处理的次数行号) 例如: sed -n '2{=;p}' infile
 n  读入下一行到模式空间 例:'4{n;d}' 删除第5行
 N  是追加下一行到模式空间,再把当前行和下一行同时应用后面的命令
 R 两个文件个行输出
 r 输出一行之后另个文件全不输出之后再输出前一个文件的另一行
 c
 i 对内存操作
P 输出当前模式空间中匹配的第一部分(第一个字符到第一个换行符为止)
D 从第一个字符删除到第一个换行符结束 它不会导入新的输入行 而是返回输入行顶部继续执行
[root@stu93 ~]# sed -n 's/root/ABCDEF/gp' /etc/passwd

ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin


[root@stu93 ~]# sed -n 's/root/ABCDEF/2p' /etc/passwd
root:x:0:0:ABCDEF:/root:/bin/bash
[root@stu93 ~]# sed -n 's/root/ABCDEF/3p' /etc/passwd
root:x:0:0:root:/ABCDEF:/bin/bash
[root@stu93 ~]# sed -n 's/root/ABCDEF/gp' /etc/passwd
ABCDEF:x:0:0:ABCDEF:/ABCDEF:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin

[root@stu93 ~]#cat a.txt
123
123
123  
[root@stu93 ~]#sed -r '$!N; /^(.*)\n\1$/!P;D' a.txt
123
高级命令
NDP sed -r '$!N;/^(.*)\n\1$/!p;D'
[root@stu93 ~]# cat a
this is the unix
system and unix is like the
unix system
[root@stu93 ~]# sed 'N;s/\n/''/;s/ system/ opting system/;P;D' a
this is the unix opting system and unix is like the
unix opting system

替换
 s 字符串替换 s/old/new/

$ sed -n 's/root/ABCDEF/p' /etc/passwd

ABCDEF:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/ABCDEF:/sbin/nologin

定址
[root@stu93 ~]# cat a.txt 
beijing ,chain
shanghai ,chain
aaa
tianjin .chain
bbb
chengdu .chain


[root@stu93 ~]# sed '/^aaa/,/^bbb/{s/tianjin/TJ/;s/chain/CN/}' a.txt 
beijing ,chain
shanghai ,chain
aaa
TJ .CN
bbb
chengdu .chain


[root@stu93 sed]# sed -n '1,3s/root/AA/gp' passwd
AA:x:0:0:AA:/AA:/bin/bash
[root@stu93 ~]# sed '=' /etc/passwd | sed 'N;s/\n/ /' 每两行处理为一行

三行处理成一行
[root@stu93 ~]# cat b.txt 
2010-09-23
192.168.0.1
shutdown
2010-09-22
192.168.0.2
reboot
2010-09-24
192.168.0.3
init 0
[root@stu93 ~]#  sed 'N;N; s/\n/ /g' b.txt
2010-09-23 192.168.0.1 shutdown
2010-09-22 192.168.0.2 reboot
2010-09-24 192.168.0.3 init 0

连着的多个空行变为一个空行输出
[root@stu93 ~]# cat c.txt 
1111111


3333




666666666

100000000
[root@stu93 ~]# sed '/^$/{N; /^\n$/D }' c.txt  D 删除第一个空行
[root@stu93 ~]# sed '/^$/d;$!G' c.txt      $!G表示最后一行不执行G规则
1111111


3333


666666666


100000000
[root@stu93 ~]# time sed '2q' a.txt   q 对大文件操作较快
[root@stu93 ~]# time sed -n '1,2p' a.txt 对小文件可以
\(\) 保存被匹配的字符 以备反向引用\N时使用 最多9个标签 标签顺序从左至右
& 替换时使用,在不定义标签时使用(反向引用)

试做:
   
删除第一个单词


删除最后一个单词


将第一个单词和最后一个单词兑换位置



y 字符替换(变形)


工作模式 模式空间和保持空间介绍



[root@stu93 ~]# sed  '1{p;p}' a.txt
11111111
11111111
11111111
22222222
33333333
44444444
55555555
66666666
置换 模式空间和保持空间(暂存空间)
 h 把模式空间内容覆盖到保持空间中
 H 把模式空间内容追加到保持空间中
 g 把保持空间内容覆盖到模式空间中
 G 把保持空间内容追加到模式空间中
 x 交换模式空间与保持空间的内容


[root@stu93 ~]# cat test.sh 
1111111
2222222
3333333
4444444
[root@stu93 ~]# sed  '{1h;2,3H;4G}'  ./test.sh 
1111111
2222222
3333333
4444444
1111111
2222222
3333333
[root@stu93 ~]# sed  '{1h;2x;3g;$G}'  ./test.sh 
1111111
1111111
2222222
4444444
2222222

[root@stu93 sed]# sed '1H;2,3{G};$g' xyz.txt 
1111111
2222222


1111111
3333333


1111111


1111111


[root@stu93 sed]# sed '1h;2,3H;$!G' xyz.txt 
1111111
1111111

2222222
1111111
2222222

3333333
1111111
2222222
3333333
                                                                                                                                                                                                                                                                                                                                                                                                     
4444444
cmd qianhou
sed null\n
1h 11111111
$!G 1111  11111111
==>1111  1111
2H 22221111 2222
$!G 2222 1111 2222       11112222
==>2222 1111 2222
3H 33331111 2222 3333
$!G 3333 1111 2222 3333
==>3333 1111 2222 3333
$!G 4444

[root@stu93 sed]# tac xyz.txt 
4444444
3333333
2222222
1111111
[root@stu93 sed]# sed '4G;2,3{G;h;d};1{h;d};' xyz.txt 
[root@stu93 sed]# sed '4G;3{G;h;d};2{G;h;d};1{h;d};' xyz.txt 
4444444
3333333
2222222
1111111
4G 44444/n/n
=>4444/n
3{G;h;d} 3333 /n
3333 3333
3333
==>3333
2{G;h;d} 2222
2222 2222
2222
==>2222
1{h;d} 1111 1111
1111
==>1111
[root@stu93 sed]# sed  '1!G;h;$!d' xyz.txt

试做题
奇数行和偶数行互换
[root@stu93 ~]# cat 3 .txt
1
2
11
22
111
222
[root@stu93 ~]# sed -e '/1/{h;d}' -e '/2/{G}' 3.txt
每行的后面加空行
[root@stu93 ~]# sed 'G' 3.txt
每行的后面加2个空行
[root@stu93 ~]# sed 'G;G' 3txt
显示文件的前10行
[root@stu93 ~]# sed -n '1,10p' /etc/passwd




每行的前面加空行
[root@stu93 ~]# sed  -e 'x;P;x'  3.txt


将第一行插入到每个偶数行的后面


$ sed  '1h;0~2G' a.txt


11111111


22222222


11111111


33333333


44444444


11111111


55555555


66666666


11111111


$


颠倒输出


[root@stu93 ~]#  sed '1!G;h;$!d' rev.txt
[root@stu93 ~]# sed -n '1!G;h;$p' 3


xyz


def


abc

脚本方法
四 编写sed脚本


模式空间
sed   -e  ‘s/pig/cow/’ -e ‘s/cow/horse/’
sed   -e ‘s/cow/horse/’ -e ‘s/pig/cow/’
 
寻址上的全局透视
全局操作   范例file2.txt
$ sed '/Beijing/s/CN/China/g' file2.txt


删除所有的行
d
删除文件的最后两行
[root@stu93 ~]# sed 'N;$!P;$!D;$d' c.txt 
只删除第一行
1d


使用寻址符号$,删除最后一行
$d


删除空行,正则表达式必须封闭在斜杠//当中
/^$/d


删除.TS和.TE标记的tbl输入
/^\.TS/,/^\.TE/d


删除第五行到结尾所有的行
5,$d

混合使用行地址和模式地址
$ sed '1,/^$/d' file2.txt


删除除了那些行以外的行
1,5!d
分组命令
/^\.TS/,/^\.TE/{
      /^$/d
}


/^\.TS/,/^\.TE/{
/^$/d
  s/^\.ps 10/.ps 8/
  s/^\.vs 12/.vs 10/
}

     -f 参数 引用脚本(脚本的末尾不能有空格制表符或其他文本)
# cat sed.sh 
2,4d
s/777/seker/
s/999/seker&seker/
# sed -f sed.sh test.txt 
1111111
5555555
6666666
seker7777
8888888
seker999seker9999
#


  在脚本中指明解释器为sed
# cat sed.sh 
#!/bin/sed -f
2,4d
s/777/seker/
s/999/seker&seker/
# ./sed.sh test.txt 
1111111
5555555
6666666
seker7777
8888888
seker999seker9999



高级流控命令 b分支 t测试
分支命令用于无条件转移,测试命令用于有条件转移


分支 branch
   跳转的位置与标签相关联
如果有标签则跳转到标签所在的后面行继续执行
如果没有标签则跳转到脚本的结尾处.
   标签 以冒号开始后接标签名 不要在标签名前后使用空格
跳转到标签指定位置
:top
  cmd1
  cmd2
/aa/b top
cmd3




cmd1
/aa/b end
cmd2
:end
cmd3


cmd1
/aa/b dothree
cmd2
b
:dothree
cmd3

[root@stu254 ~]# grep seker /etc/passwd
seker:x:500:500::/home/seker:/bin/bash
[root@stu254 ~]#
[root@stu254 ~]# grep seker /etc/passwd |sed ':top;s/seker/blues/;/seker/b top;s/5/555/' 
blues:x:55500:500::/home/blues:/bin/bash
[root@stu254 ~]# 


命令分析:让单次替换(cmd1)循环执行,直到条件不满足
:top; 定义一个top标签
s/seker/blues/; cmd1
/seker/b top; 如果模式匹配则跳转到top标签
s/5/555/ 当上一条模式不匹配时,既会继续执行这一条


选择执行
[root@stu254 ~]#  grep 'seker' /etc/passwd |sed 's/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/'
blues:x:66600:500::/home/seker:/bin/bash
[root@stu254 ~]# 


zorro:x:501:501::/home/zorro:/bin/bash
[root@stu254 ~]#  grep 'zorro' /etc/passwd |sed 's/seker/blues/;/seker/b end;s/5/555/;:end;s/5/666/'
zorro:x:6665501:501::/home/zorro:/bin/bash
[root@stu254 ~]# 


命令分析: 执行cmd1,再去模式匹配,成功则跳转到cmd3开始执行,否则(模式不匹配)会按命令顺序逐个执行
s/seker/blues/; cmd1
/seker/b end;
s/5/555/; cmd2
:end;
s/5/666/ cmd3


另一种选择执行
[root@stu254 ~]#  grep 'seker' /etc/passwd |sed 's/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/'
blues:x:66600:500::/home/seker:/bin/bash


[root@stu254 ~]#  grep 'zorro' /etc/passwd |sed 's/seker/blues/;/seker/b end;s/5/555/;b;:end;s/5/666/'
zorro:x:55501:501::/home/zorro:/bin/bash
[root@stu254 ~]# 


命令分析: 执行cmd1;模式匹配cmd2成功则执行cmd3;否则执行cmd2,再跳转到脚本末尾 
s/seker/blues/; cmd1
/seker/b end;
s/5/555/;  cmd2
b;
:end;
s/5/666/ cmd3




测试命令,如果前一个替换命令执行成功则跳转到脚本末尾 (case结构)
[root@stu254 ~]#  grep 'seker' /etc/passwd |sed 's/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/'
ABC:x:500:500::/home/seker:/bin/bash


[root@stu254 ~]#  grep 'zorro' /etc/passwd |sed 's/seker/ABC/;t;s/home/DEF/;t;s/bash/XYZ/'
zorro:x:501:501::/DEF/zorro:/bin/bash
[root@stu254 ~]#


与标签关联,跳转到标签位置
[root@stu254 ~]#  grep 'seker' /etc/passwd |sed 's/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/'
ABC:x:500:500::/home/seker:/bin/XYZ
[root@stu254 ~]#
  
[seker@seker ~]$ grep 'zorro' /etc/passwd |sed 's/seker/ABC/;t end;s/home/DEF/;t;:end;s/bash/XYZ/'
zorro:x:501:501::/DEF/zorro:/bin/bash


[seker@seker ~]$


runsed 对输入文件作永久性改变
#!/bin/bash
        for x
do
        echo "editing $x: \c"
        if test "$x" = sedscr;then


        echo "not editing sedscript"
        elif test -s $x;then
        sed -f sedscr $x > /tmp/$x$$
        if test -s /tmp/$x$$
        then
                if cmp -s /tmp/$x$$
                then
                        echo "file not changed: \c"
                else
                        mv $x.bak # save original, just in case
                        cp /tmp/$x$$ $x
                fi
                echo "done"
                else
                echo "Sed produced an empty file\c"
                echo "- check your sedscript."
        fi
        rm -f /tmp/$x$$
        else
                echo "original file is empty."
        fi
        done
        echo "all done"

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24492954/viewspace-1061863/,如需转载,请注明出处,否则将追究法律责任。

上一篇: oracle 热备脚本 .
请登录后发表评论 登录
全部评论

注册时间:2011-04-09

  • 博文量
    41
  • 访问量
    239371