sed命令相关技巧

sed 替换回车

sed '/^$/!{:n;N;/\n$/!s/\n//;tn;}' xxx

文件最后附加新行

sed '$aNEW-LINE' xxx.txt

回车替换为空格

sed ':a;N;$!ba;s/\n +/ /g' xxx

sed 替换单引号

例如下面的例子中通过 sed 命令将 xx'yy 替换为 zz@tt

sed -i 's/xx'\''yy/zz@tt/g' xxx

输出匹配行后面的行

输出匹配行加上下一行:

sed -n '/pattern/{N;p;}' xxx

如果需要附加更多的行,例如下面表示再附加 3 行:

sed -n '/pattern/,+3p' xxx

输出匹配行前面的行

输出匹配行的前面一行:

sed -n '/pattern/{x;p;d;}; x' xxx

工作机制:

sed has a hold space and a pattern space. New lines are read into the pattern space. The idea of this script is the the previous line is saved in the hold space.

  • This the current line contains pattern, then do:

    x : swap the pattern and hold space so that the prior line is in the pattern space

    p : print the prior line

    d : delete the pattern space and start processing next line

  • x

    This is executed only on lines which do not contain age is : 10. In this case, save the current line in the hold space.

输出匹配行的前面一行加上匹配行:

sed -n '/pattern/{x;p;x;p}; h' xxx

查找匹配行之后多次替换

多个匹配命令以分号隔开,匹配后的所有命令用大括号括起来:

sed -n '/dc-version/{s/^.*value="//;s/".*$//;p}' xxx

替换中使用匹配内容

  • 替换块中使用 & 表示完整匹配内容:

    ~ # echo "BEGIN (254:6) END" | sed -E 's/\([0-9]*:([0-9]*\))/, &/'
    BEGIN , (254:6) END
    
  • 替换块中使用 \1 \2 等表示对应的子匹配块

    ~ # echo "BEGIN (254:6) END" | sed -E 's/:([0-9]*\))/, \1/'
    BEGIN (254, 6) END
    ~ # echo "BEGIN (254:6) END" | sed -E 's/\(([0-9]*):([0-9]*)\)/[\1, \2]/'
    BEGIN [254, 6] END
    
  • 替换块之后使用数字表示替换第几个匹配项

    ~ # echo "BEGIN (254:6:117) END" | sed -E 's/([0-9]+)/666/2'
    BEGIN (254:666:117) END
    

跟随符号链接

sed 命令如果指定了 -i 参数直接修改文件,对于符号链接文件(例如 new.conf 为指向 old.conf 的符号链接),默认会保持 old.conf 不变,new.conf 符号链接被删除,并生成新的 new.conf 文件。

sed 增加 --follow-symlinks 参数就可以修改指向的 old.conf 源文件,并保持 new.conf 符号链接不变。