行编辑工具:sed

风行水上 @ 2011-02-16 15:27:33
标签:

    sed 是一个命令,更是一个有趣的文本编辑器。这类编辑器有时也可以称为“行编辑器”。

    所谓“行编辑器”,是指它每次只编辑一行。这使得它的结构很简单,简单到文本编辑也可以成为一种思维考验。

    sed 中用于存储文本的地方只有两个区域:

    • 一个称为 PATTERN SPACE,用来存放当前读入的行。
    • 另一个称为 HOLD SPACE,用来存放临时文本。

    就是靠这仅有的两个 SPACE 使得 SED 可以完成一些复杂的文本编辑操作。这些操作往往借助巧妙的时间、空间管理来完成。

    对于这种仅利用时间和两个空间的文本编辑,时常让我感觉到一种精微中的宏大。所谓”一花一世界,一沙一乾坤。掌中握无限,刹那在永恒”。

    # Sed Diagram (Sed 概览图)
    # by Sean Zhang (http://noyesno.net/) at Feb, 2011
    
    Address:  // ,
     Regexp:  \{m,n\}
              \(\)
              \1 \2 ... \9
    
                  +----------------+
                  |     Input      |
                  +----------------+
                          |
                          |
                          | 
                  +-------V--------+          +--------------+ 
        s y d D   |                |---h H--->|              | 
      ----------->| Pattern Space  |<----x--->|  Hold Space  | 
        b t N     |                |<--g G----|              | 
                  +----------------+          +--------------+ 
                          |
                        q | n N p P r w = a\ c\ i\
                          |
                  +-------V--------+
                  |    Output      |
                  +----------------+
    

    sed 语法和命令

    • d : 删除 Pattern Space 中的内容 (delete)
    • D : 删除 Pattern Space 中的第一行内容
    • g : 使用 Hold Space 的内容替换 Pattern Space 中的内容 (get)
    • G : 追加 Hold Space 中的内容到 Pattern Space
    • h : 使用 Pattern Space 的内容替换 Hold Space 中的内容 (hold)
    • H : 追加 Pattern Space 中的内容到 Hold Space
    • n : 输出 Pattern Sapce 中的内容,并读入下一行 (next)
    • N : 追加下一行内容到 Pattern Space中
    • p : 输出 Pattern Space 中的内容到 stdout (print)
    • P : 输出 Pattern Space 中的第一行
    • q : 退出 (quit)
    • r file : 输出文件file的内容到 stdou
    • s/abc/def/g : 对 Pattern Space 中的内容进行替换操作。g 表示全局替换
    • w file : 追加 Pattern Space 中的内容到文件file中
    • x : 交换 Pattern Space 和 Hold Space 的内容 (exchange)
    • y/a/b/ : 对 Pattern Space 中的内容进行字符替换。类似于 tr命令
    • = :输出当前行号
    • # : 注释行

    应用实例

    假设有下面的文件内容

    aaa
    bbb
    ccc
    ddd
    

    多个Pattern的逻辑与逻辑或

    # grep for AAA and BBB and CCC (in any order)
    sed '/AAA/!d; /BBB/!d; /CCC/!d'
    
    # grep for AAA or BBB or CCC (emulates "egrep") 
    sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
    

    上面利用了两个不常用的控制命令:

    • !: 表示对不匹配模式的行进行操作
    • b: 是分支跳转命令(branch),省略要跳转到的label时,则跳转到程序的结束

    参考文章:Handy One-Liners for SED

    替换匹配行的前一行

    把包含字符串"ccc"的前一行的内容替换为 “bingo”

    sed '/ccc/ {x ; s/.*/bingo/; x} ; x ; 1 d ; $ G'
    
    • 为了能够处理前一行,需要保存这个前一行内容,可以使用 Hold Space 来保存
    • 每次输出的其实是前一行,同时要保存当前行。这就是第三个x的作用
    • 前两个x用于替换存储在Hold Space的前一行
    • 1$ 两个模式用来处理文件开始(空行)和结束行(最后一行还在Hold Space中)

    网络资源

    标签:

      分享到:
      comments powered by Disqus

      26/28ms