语法一

1
sed [options] {sed-commands} {input-file}

例子:

1
2
3
4
5
6
# -n表示取消默认输出,p表示打印行
[root@yyl ~]# sed -n 'p' passwd
# 只打印第三行
[root@yyl ~]# sed -n '3p' passwd
# 打印1,3行
[root@yyl ~]# sed -n '1,3p' passwd

语法二

1
$sed [options] -f {sed-commands-in-a-file} {input-file}

例子:

1
2
3
4
5
6
7
8
# 打印以root开头或者nobody开头的行
[root@yyl ~]# cat sed_exp1.sed
/^root/ p
/^nobody/ p
[root@yyl ~]# sed -n -f sed_exp1.sed passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Nobody:/:/sbin/nologin
[root@yyl ~]#

语法三

1
sed [options] -e {sed-command-1} -e {sed-command-2} {input-file}

例子:

1
2
3
4
5
6
7
8
9
10
11
12
# 打印以root开头或者nobody开头的行
[root@yyl ~]# sed -n -e '/^root/ p' -e '/^nobody/ p' passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Nobody:/:/sbin/nologin
# 或者
[root@yyl ~]# sed -n \
> -e '/^root/ p' \
> -e '/^nobody/ p' \
> passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Nobody:/:/sbin/nologin
[root@yyl ~]#

语法四

1
2
3
4
sed [options] '{
sed-command-1
sed-command-2
}' input-file

例子:

1
2
3
4
5
6
# 打印以root开头或者nobody结尾的行
[root@yyl ~]# sed -n '{
> /^root/ p
> /nobody$/ p
> }' passwd
root:x:0:0:root:/root:/bin/bash

行后增加语法

1
sed '[address] a the-line-to-append' input-file

例子:

1
2
3
4
5
6
7
8
9
[root@yyl ~]# sed '2 a 108,Donald Stufft, Nebula' example2.txt
101,Ian Bicking,Mozilla
102,Hakim El Hattab,Whim
108,Donald Stufft, Nebula
103,Paul Irish,Google
104,Addy Osmani,Google
105,Chris Wanstrath,Github
106,Mattt Thompson,Heroku
107,Ask Solem Hoel,VMware

行前插入语法

1
sed '[address] i the-line-to-insert' input-file

例子:

1
2
3
4
5
6
7
8
9
[root@yyl ~]# sed '2 i 108,Donald Stufft, Nebula' example2.txt
101,Ian Bicking,Mozilla
108,Donald Stufft, Nebula
102,Hakim El Hattab,Whim
103,Paul Irish,Google
104,Addy Osmani,Google
105,Chris Wanstrath,Github
106,Mattt Thompson,Heroku
107,Ask Solem Hoel,VMware

修改行语法

1
sed '[address] c the-line-to-insert' input-file

例子:修改符合Paul行为…

1
2
3
4
5
6
7
8
[root@yyl ~]# sed '/Paul/ c 108,Donald Stufft, Nebula' example2.txt
101,Ian Bicking,Mozilla
102,Hakim El Hattab,Whim
108,Donald Stufft, Nebula
104,Addy Osmani,Google
105,Chris Wanstrath,Github
106,Mattt Thompson,Heroku
107,Ask Solem Hoel,VMware

其他

  1. l 会显示隐藏字符比如 '\\t制表符' $ \\r

    1
    2
    3
    #    显示第一行的隐藏字符
    [root@yyl ~]# sed -n '1l' example2.txt
    \t101,Ian Bicking,Mozilla$
  2. l5 会在5个字符数之后进行换行。

    1
    2
    3
    4
    5
    6
    7
    [root@yyl ~]# sed -n 'l5' example2.txt
    \t10\
    1,Ia\
    n Bi\
    ckin\
    g,Mo\
    zill\
  3. = 会先打印每行行号

    1
    2
    3
    4
    5
    [root@yyl ~]# sed '=' example2.txt
    1
    101,Ian Bicking,Mozilla
    2
    102,Hakim El Hattab,Whim
  4. y或翻译你要转换的字符,这里I会转化成i,B转换成b

    1
    2
    [root@yyl ~]# sed 'y/IB/ib/' example2.txt | head -1
    101,ian bicking,Mozilla

sed 流

  1. 执行
  2. 打印
  3. 重复

测试文件 example.txt

1
2
3
4
5
6
7
8
[root@yyl ~]# cat example2.txt
101,good good study, day day up
102,Come on, chop-chop, we are running late
103,He always blah blah and I've heard it all before
104,He is a bit of a goody-goody
105,I think you might pooh-pooh this idea
106,Let's divide the prize fifty-fifty
107,In the end he was forced to resign but it was all very hush-hush

测试文件 example2.txt

1
2
3
4
5
6
7
101,Ian Bicking,Mozilla
102,Hakim El Hattab,Whim
103,Paul Irish,Google
104,Addy Osmani,Google
105,Chris Wanstrath,Github
106,Mattt Thompson,Heroku
107,Ask Solem Hoel,VMware

文本替换

语法:

1
sed '[address-range|pattern-range] s/original-string/replacement-string/[substitute-flags]' inputfile

例子

  1. 替换Google为Github(默认只会替换每一行的第一个 替换全部使用 ‘s/good/bad/g’)

    1
    2
    [root@yyl ~]# sed 's/good/bad/' example.txt | head -1
    101,bad good study, day day up
  2. 替换匹配Come的行里面的chop为chops

    1
    2
    3
    4
    5
    6
    7
    8
    [root@yyl ~]# sed '/Come/s/chop/chops/' example.txt
    101,good good study, day day up
    102,Come on, chops-chop, we are running late
    103,He always blah blah and I've heard it all before
    104,He is a bit of a goody-goody
    105,I think you might pooh-pooh this idea
    106,Let's divide the prize fifty-fifty
    107,In the end he was forced to resign but it was all very hush-hush
  3. 默认只会替换每行的第一个

    1
    2
    [root@yyl ~]# sed '1s/g/G/' example.txt | head -1
    101,Good good study, day day up
  4. g可以替换每行的全部符合

    1
    2
    [root@yyl ~]# sed '1s/g/G/g' example.txt | head -1
    101,Good Good study, day day up
  5. 可以直接指定想要替换的第N个匹配项,这里是第二个

    1
    2
    [root@yyl ~]# sed '1s/g/G/2' example.txt | head -1
    101,good Good study, day day up
  6. 使用w将能够替换的行重定向写到output.txt

    1
    2
    3
    4
    [root@yyl ~]# sed '1s/g/G/g w output.txt' example.txt | head -1
    101,Good Good study, day day up
    [root@yyl ~]# cat output.txt
    101,Good Good study, day day up
  7. 还可以使用i忽略匹配的大小写,有的版本可能不能用

    1
    2
    [root@yyl ~]# sed '1s/Good/GOOD/i' example.txt | head -1
    101,GOOD good study, day day up
  8. 给每行前和后都添加点字符 echo “(当前行)”;

    1
    2
    3
    4
    5
    6
    7
    8
    [root@yyl ~]# sed 's/\(.*\)/echo \"\1\";/' example.txt
    echo "101,good good study, day day up";
    echo "102,Come on, chop-chop, we are running late";
    echo "103,He always blah blah and I've heard it all before";
    echo "104,He is a bit of a goody-goody";
    echo "105,I think you might pooh-pooh this idea";
    echo "106,Let's divide the prize fifty-fifty";
    echo "107,In the end he was forced to resign but it was all very hush-hush";
  9. 执行命令

    1
    2
    3
    4
    5
    6
    [root@yyl ~]# cat commond.txt
    /etc/passwd
    /etc/group
    [root@yyl ~]# sed 's/^/ls -l /e' commond.txt
    -rw-r--r--. 1 root root 879 5月 25 12:39 /etc/passwd
    -rw-r--r--. 1 root root 476 6月 12 23:10 /etc/group
  10. sed分隔符不只可以使用’/‘ 这里使用’#’

    1
    2
    3
    4
    [root@yyl ~]# cat passwd | head -1
    root:x:0:0:root:/root:/bin/bash
    [root@yyl ~]# cat passwd | head -1 | sed 's#/bin/bash#/sbin/bash#'
    root:x:0:0:root:/root:/sbin/bash
  11. 替换覆盖

    1
    2
    3
    4
    5
    [root@yyl ~]# sed '{
    > s/good/GOOD/
    > s/GO/go/
    > }' example.txt | head -1
    101,goOD good study, day day up
  12. 神奇的 & 符号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@yyl ~]# sed 's/^[0-9][0-9][0-9]/[&]/g' example.txt
    [101],good good study, day day up
    [102],Come on, chop-chop, we are running late
    [103],He always blah blah and I've heard it all before
    [104],He is a bit of a goody-goody
    [105],I think you might pooh-pooh this idea
    [106],Let's divide the prize fifty-fifty
    [107],In the end he was forced to resign but it was all very hush-hush
    [root@yyl ~]# sed 's/good/&test/' example.txt | head -1
    101,goodtest good study, day day up
  13. 元字符\u \l \U \L :转换为大写/小写字符
    \U 将所有自负转换成大写
    \u 将首字符转成大写
    \L 将所有字符转成小写
    \l 将首字符转成小写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@yyl ~]# sed 's/good/\U&/' example.txt | head -1
    101,GOOD good study, day day up
    [root@yyl ~]# sed 's/good/\U&/g' example.txt | head -1
    101,GOOD GOOD study, day day up
    [root@yyl ~]# sed 's/good/\u&/g' example.txt | head -1
    101,Good Good study, day day up
    [root@yyl ~]# sed 's/^.*$/\U&/' example.txt | head -1
    101,GOOD GOOD STUDY, DAY DAY UP
    [root@yyl ~]# sed 's/good/\U&/g' example.txt | head -1 | sed 's/GOOD/\L&/'
    101,good GOOD study, day day up
    [root@yyl ~]# sed 's/good/\U&/g' example.txt | head -1 | sed 's/GOOD/\l&/'
    101,gOOD GOOD study, day day up
  14. \E能打断\L或者\U改变大小写

    1
    2
    3
    4
    [root@yyl ~]# sed 's/Ian/\Uian/' example2.txt|head -1
    101,IAN Bicking,Mozilla
    [root@yyl ~]# sed 's/Ian/\Uia\En/' example2.txt|head -1
    101,IAn Bicking,Mozilla
  15. 使用()获取正则匹配的内容,使用\1 获取第一个括号的内容,使用\2获取第二个括号里面的内容
    例如:获取passwd文件的用户名

    1
    2
    [root@yyl ~]# sed 's/\(^[a-z-]\+\):.*/\1/' passwd | head -1
    root
  16. 使用()替换部分字符串

    1
    2
    [root@yyl ~]# echo "w1w2w3"|sed 's/\(w1\)\(w2w3\)/\2\1/'
    w2w3w1
  17. ^ 表示匹配以什么开头

    1
    2
    [root@yyl ~]# sed -n '/^101/ p' example2.txt
    101,Ian Bicking,Mozilla
  18. $表示匹配以什么结尾

    1
    2
    [root@yyl ~]# sed -n '/Github$/ p' example2.txt
    105,Chris Wanstrath,Github
  19. .表示单个字符,下面的匹配一个逗号然后I然后2个单字符

    1
    2
    [root@yyl ~]# sed -n '/,I../ p' example2.txt
    101,Ian Bicking,Mozilla
  20. *表示匹配0个或者多个, \+表示匹配一个或者多个, \?表示匹配0个或者1个
    [0-9]表示匹配数字,下面匹配包含3或者4的行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [root@yyl ~]# sed -n '/att*/ p' example2.txt
    102,Hakim El Hattab,Whim
    105,Chris Wanstrath,Github
    106,Mattt Thompson,Heroku
    [root@yyl ~]# sed -n '/t\+/ p' example2.txt
    102,Hakim El Hattab,Whim
    105,Chris Wanstrath,Github
    106,Mattt Thompson,Heroku
    [root@yyl ~]# sed -n '/Ho\?e/ p' example2.txt
    106,Mattt Thompson,Heroku
    107,Ask Solem Hoel,VMware
    [root@yyl ~]# sed -n '/[34]/ p' example2.txt
    103,Paul Irish,Google
    104,Addy Osmani,Google
    • 表示范围,这里匹配3,4,5
      1
      2
      3
      4
      [root@yyl ~]# sed -n '/[3-5]/ p' example2.txt
      103,Paul Irish,Google
      104,Addy Osmani,Google
      105,Chris Wanstrath,Github
  21. | 表示或者的关系

    1
    2
    3
    [root@yyl ~]# sed -n '/3\|5/ p' example2.txt
    103,Paul Irish,Google
    105,Chris Wanstrath,Github
  22. {m} 表示前面的匹配的重复次数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@yyl ~]# cat numbers.txt
    1
    12
    123
    1234
    12345
    123456
    [root@yyl ~]# sed -n '/^[0-9]\{3\}$/ p' numbers.txt
    123
  23. {m,n } 表示匹配m-n的次数都算

    1
    2
    3
    [root@yyl ~]# sed -n '/^[0-9]\{3,4\}$/ p' numbers.txt
    123
    1234
  24. 删除所有注释和空行

    1
    [root@yyl ~]# sed -e 's/#.*//' -e '/^$/ d' /etc/profile
  25. 转化windows文件到unix格式(这个没看懂)

    1
    sed 's/.$//' filename

sed 可执行脚本

1
2
3
4
5
6
7
8
9
[root@yyl ~]# cat testscript.sed
#!/usr/bin/sed -nf
/root/ p
/nobody/ p
[root@yyl ~]# chmod u+x testscript.sed
[root@yyl ~]# ./testscript.sed passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

sed 修改源文件和备份

  1. -i 会修改源文件,但是可以同时使用bak备份

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    [root@yyl ~]# sed -ibak 's/Ian/IAN/' example2.txt
    [root@yyl ~]# ls -l | grep example2.txt
    -rw-r--r--. 1 root root 173 6月 13 15:12 example2.txt
    -rw-r--r--. 1 root root 173 6月 13 10:37 example2.txtbak
    [root@yyl ~]# cat example2.txt
    101,IAN Bicking,Mozilla
    102,Hakim El Hattab,Whim
    103,Paul Irish,Google
    104,Addy Osmani,Google
    105,Chris Wanstrath,Github
    106,Mattt Thompson,Heroku
    107,Ask Solem Hoel,VMware
    [root@yyl ~]# cat example2.txtbak
    101,Ian Bicking,Mozilla
    102,Hakim El Hattab,Whim
    103,Paul Irish,Google
    104,Addy Osmani,Google
    105,Chris Wanstrath,Github
    106,Mattt Thompson,Heroku
    107,Ask Solem Hoel,VMware
  2. 1还可以使用这种语法 --in-place=后缀

    1
    2
    3
    4
    5
    [root@yyl ~]# sed --in-place=_bak 's/IAN/Ian/' example2.txt
    [root@yyl ~]# ls -l | grep example2.txt
    -rw-r--r--. 1 root root 173 6月 13 15:16 example2.txt
    -rw-r--r--. 1 root root 173 6月 13 10:37 example2.txtbak
    -rw-r--r--. 1 root root 173 6月 13 15:12 example2.txt_bak

###

sed命令—行定位

  1. 打印出文件的第三行 (定位单行)

    1
    2
    [root@yyl ~]# nl example2.txt | sed -n '3p'
    3 103,Paul Irish,Google
  2. 打印出文件的第2到第3行 (多行定位)

    1
    2
    3
    [root@yyl ~]# nl example2.txt | sed -n '2,3p'
    2 102,Hakim El Hattab,Whim
    3 103,Paul Irish,Google
  3. 打印出包含Paul的行 (单行定位)

    1
    2
    [root@yyl ~]# nl example2.txt | sed -n '/Paul/p'
    3 103,Paul Irish,Google
  4. 打印出包含Paul开始的行到包含Chris结束的行 (多行定位)

    1
    2
    3
    4
    [root@yyl ~]# nl example2.txt | sed -n '/Paul/,/Chris/p'
    3 103,Paul Irish,Google
    4 104,Addy Osmani,Google
    5 105,Chris Wanstrath,Github
  5. 从Paul开始的行到Chris结束的行,都不要

    1
    2
    3
    4
    5
    [root@yyl ~]# nl example2.txt | sed -n '/Paul/,/Chris/!p'
    1 101,Ian Bicking,Mozilla
    2 102,Hakim El Hattab,Whim
    6 106,Mattt Thompson,Heroku
    7 107,Ask Solem Hoel,VMware
  6. 打印出文件非第5行的内容 (单行取反)

    1
    2
    3
    4
    5
    6
    7
    [root@yyl ~]# nl example2.txt | sed -n '5!p'
    1 101,Ian Bicking,Mozilla
    2 102,Hakim El Hattab,Whim
    3 103,Paul Irish,Google
    4 104,Addy Osmani,Google
    6 106,Mattt Thompson,Heroku
    7 107,Ask Solem Hoel,VMware
  7. 打印出文件的非第2到五行内容 (多行取反)

    1
    2
    3
    4
    [root@yyl ~]# nl example2.txt | sed -n '2,5!p'
    1 101,Ian Bicking,Mozilla
    6 106,Mattt Thompson,Heroku
    7 107,Ask Solem Hoel,VMware
  8. 步进获取行的内容(从第2行开始 步长为3)

    1
    2
    3
    4
    [root@yyl ~]# nl example2.txt | sed -n '2~3p'
    2 102,Hakim El Hattab,Whim
    5 105,Chris Wanstrath,Github
    结果为2,5,8,11......行
  9. 从找到开始打印到第五行(Paul 在第3行)

    1
    2
    3
    4
    [root@yyl ~]# nl example2.txt | sed -n '/Paul/,5p'
    3 103,Paul Irish,Google
    4 104,Addy Osmani,Google
    5 105,Chris Wanstrath,Github
  10. 从找到的地方开始 在多输出3行

    1
    2
    3
    4
    5
    [root@yyl ~]# nl example2.txt | sed -n '/Paul/,+3p'
    3 103,Paul Irish,Google
    4 104,Addy Osmani,Google
    5 105,Chris Wanstrath,Github
    6 106,Mattt Thompson,Heroku

删除行

  1. 删除所有行

    1
    [root@yyl ~]# nl example2.txt | sed 'd'
  2. 只删除第二行

    1
    2
    3
    4
    5
    6
    7
    [root@yyl ~]# nl example2.txt | sed '2d'
    1 101,Ian Bicking,Mozilla
    3 103,Paul Irish,Google
    4 104,Addy Osmani,Google
    5 105,Chris Wanstrath,Github
    6 106,Mattt Thompson,Heroku
    7 107,Ask Solem Hoel,VMware
  3. 删除第1到4行

    1
    2
    3
    4
    [root@yyl ~]# nl example2.txt | sed '1,4d'
    5 105,Chris Wanstrath,Github
    6 106,Mattt Thompson,Heroku
    7 107,Ask Solem Hoel,VMware
  4. 按步长删除(删除奇数行)

    1
    2
    3
    4
    [root@yyl ~]# nl example2.txt | sed '1~2d'
    2 102,Hakim El Hattab,Whim
    4 104,Addy Osmani,Google
    6 106,Mattt Thompson,Heroku
  5. 删除匹配的行(同样支持 ‘/Paul/,4d’ | ‘/Paul/,+3d’ | ‘/Paul/,/Chris/d’ | ‘/Paul/,/Chris/!d’)

    1
    2
    3
    4
    5
    6
    7
    [root@yyl ~]# nl example2.txt | sed '/Paul/d'
    1 101,Ian Bicking,Mozilla
    2 102,Hakim El Hattab,Whim
    4 104,Addy Osmani,Google
    5 105,Chris Wanstrath,Github
    6 106,Mattt Thompson,Heroku
    7 107,Ask Solem Hoel,VMware
  6. 删除空行 注释行(这块没有用nl命令 nl命令会影响 sed执行效果)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    [root@yyl ~]# cat example2.txt
    101,Ian Bicking,Mozilla
    102,Hakim El Hattab,Whim
    103,Paul Irish,Google
    104,Addy Osmani,Google
    105,Chris Wanstrath,Github
    #1234567777

    106,Mattt Thompson,Heroku
    107,Ask Solem Hoel,VMware

    [root@yyl ~]# sed '/^#/d' example2.txt // 删除注释行
    101,Ian Bicking,Mozilla
    102,Hakim El Hattab,Whim
    103,Paul Irish,Google
    104,Addy Osmani,Google
    105,Chris Wanstrath,Github

    106,Mattt Thompson,Heroku
    107,Ask Solem Hoel,VMware

    [root@yyl ~]# sed '/^$/d' example2.txt // 删除空行
    101,Ian Bicking,Mozilla
    102,Hakim El Hattab,Whim
    103,Paul Irish,Google
    104,Addy Osmani,Google
    105,Chris Wanstrath,Github
    #1234567777
    106,Mattt Thompson,Heroku
    107,Ask Solem Hoel,VMware

重定向

  1. 将example.txt内容重定向写到output.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [root@yyl ~]# ls -l | grep txt
    -rw-r--r--. 1 root root 186 6月 13 09:55 example.txt
    [root@yyl ~]# sed 'w output.txt' example2.txt
    101,Ian Bicking,Mozilla
    102,Hakim El Hattab,Whim
    103,Paul Irish,Google
    104,Addy Osmani,Google
    105,Chris Wanstrath,Github
    #1234567777

    106,Mattt Thompson,Heroku
    107,Ask Solem Hoel,VMware
    [root@yyl ~]# ls -l | grep txt
    -rw-r--r--. 1 root root 186 6月 13 09:55 example2.txt
    -rw-r--r--. 1 root root 186 6月 13 09:55 output.txt
  2. 将example.txt内容重定向写到output1.txt(不会在终端输出)

    1
    2
    3
    4
    5
    [root@yyl ~]# sed -n 'w output1.txt' example2.txt
    [root@yyl ~]# ls -l | grep txt
    -rw-r--r--. 1 root root 186 6月 13 09:55 example2.txt
    -rw-r--r--. 1 root root 186 6月 13 09:56 output1.txt
    -rw-r--r--. 1 root root 186 6月 13 09:55 output.txt
  3. 只写第二行

    1
    2
    3
    [root@yyl ~]# sed -n '2w output.txt' example2.txt
    [root@yyl ~]# cat output.txt
    102,Hakim El Hattab,Whim
  4. 将第一到四行写到output.txt

    1
    2
    3
    4
    5
    6
    [root@yyl ~]# sed -n '1,4w output.txt' example2.txt
    [root@yyl ~]# cat output.txt
    101,Ian Bicking,Mozilla
    102,Hakim El Hattab,Whim
    103,Paul Irish,Google
    104,Addy Osmani,Google
  5. 将匹配Mat的行到结尾行写到output.txt(正则匹配区分大小写)
    同样支持

    '1,4w output.txt'
    '/Paul/,5w output.txt'
    '/Paul/,+1w output.txt' 
    '/Paul/,/Chris/w output.txt'
    '/Paul/,/Chris/!w output.txt'
    
1
2
3
4
5
6
[root@yyl ~]# sed -n '/mat/,$w output.txt' example2.txt
[root@yyl ~]# cat output.txt
[root@yyl ~]# sed -n '/Mat/,$w output.txt' example2.txt
[root@yyl ~]# cat output.txt
106,Mattt Thompson,Heroku
107,Ask Solem Hoel,VMware