文本处理三剑客:sed简介

文本处理三剑客:sed简介

sed是一种流编辑器,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。

处理过程

sed命令将当前处理的行读入模式空间(pattern space)进行处理,sed在该行上执行完所有命令后就将处理好的行打印到屏幕上(除非之前的命令删除了该行),sed处理完一行就将其从模式空间中删除,然后将下一行读入模式空间,进行处理、显示。处理完文件的最后一行,sed便结束运行。sed在临时缓冲区(模式空间)对文件进行处理,所以不会修改原文件,除非显示指明-i选项。

语法

sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

选项

-n:不输出模式空间的内容至屏幕,仅显示script处理后的结果;
-e<script>:以选项中的指定的script来处理输入的文本文件;
-f<script文件>:以选项中指定的script文件来处理输入的文本文件;
-r, --regexp-extended:支持使用扩展正则表达式;
-i :直接修改读取的文件内容,而不是输出到终端

地址定界

(1) 空地址:对全文进行处理;
(2) 单地址:
    #:指定行;
    /pattern/:被此模式所匹配到的每一行;
(3) 地址范围
    #1,#2:从#1行到#2行
    #1,+#2:,从#1行开始到在增加+#2行
    #,/pat1/,从第#行开始到第一次匹配到pat1行
    /pat1/,/pat2/,从匹配pat1行到匹配pat2行
    $:最后一行;
(4) 步进:~
    1~2:所有奇数行
    2~2:所有偶数行

参数

文件:指定待处理的文本文件列表。

编辑命令

d:删除;
p:显示模式空间中的内容,通常 p 会与参数 sed -n 一起运行;
a  \text:在行后面追加文本“text”,支持使用\n实现多行追加; 
i  \text:在行前面插入文本“text”,支持使用\n实现多行插入; 
c  \text:把匹配到的行替换为此处指定的文本“text”;
w /PATH/TO/SOMEFILE:保存模式空间匹配到的行至指定的文件中;
r  /PATH/FROM/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行后面;文件合并;
=:为模式匹配到的行打印行号;
!:条件取反;
    地址定界!编辑命令;
s///:查找替换,其分隔符可自行指定,常用的有s@@@, s###等;
    替换标记:
        g:全局替换;
        w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中;
        p:显示替换成功的行;

高级编辑命令

h:把模式空间中的内容覆盖至保持空间中;
H:把模式空间中的内容追加至保持空间中;
g:把保持空间中的内容覆盖至模式空间中;
G:把保持空间中的内容追加至模式空间中;
x:把模式空间中的内容与保持空间中的内容互换;
n:覆盖读取匹配到的行的下一行至模式空间中;
N:追加读取匹配到的行的下一行至模式空间中;
d:删除模式空间中的行;
D:删除多行模式空间中的所有行;

实例

[root@localhost ~]# cat -n  /tmp/test
 1  HELLO LINUX!  
 2
 3  Linux is a free unix-type opterating system.  
 4
 5  This is a linux testfile!  
 6
 7  Linux test 

替换操作 字符替换 s///

  • 替换linux为LINUX

    [root@localhost ~]# sed 's/linux/LINUX/' /tmp/test
    HELLO LINUX!  
    
    Linux is a free unix-type opterating system.  
    
    This is a LINUX testfile!  
    
    Linux test 
    
  • 仅显示替换行 p 和 -n一起使用

    [root@localhost ~]# sed -n 's/linux/LINUX/p' /tmp/test
    This is a LINUX testfile!  
    

行替换

  • 替换n行(替换第二行)

    [root@localhost ~]# sed '2chello linxu' /tmp/test
    HELLO LINUX!  
    hello linxu
    Linux is a free unix-type opterating system.  
    
    This is a linux testfile!  
    
    Linux test 
    
  • 替换第n到m行(第一到第三行)

    [root@localhost ~]#  sed '1,3chello linxu\nlet go' /tmp/test
    hello linxu
    let go
    
    This is a linux testfile!  
    
    Linux test 
    
  • 把有word行替换(替换有HELLO的行)

    [root@localhost ~]# sed '/HELLO/chello linxu' /tmp/test
    hello linxu
    
    Linux is a free unix-type opterating system.  
    
    This is a linux testfile!  
    
    Linux test 
    

删除

  • 删除第n行(删除第一行)

    [root@localhost ~]# sed '1d' /tmp/test
    
    Linux is a free unix-type opterating system.  
    
    This is a linux testfile!  
    
    Linux test 
    
  • 删除第n行和第m行(第一行和第四行)

    [root@localhost ~]# sed  -e '1d' -e '4d' /tmp/test
    
    Linux is a free unix-type opterating system.  
    This is a linux testfile!  
    
    Linux test 
    
  • 删除第n行到m行(删除第一行到第三行)

    [root@localhost ~]# sed '1,3d' /tmp/test
    
    This is a linux testfile!  
    
    Linux test 
    
  • 删除还有字符串xxx的行(带linux的行)

    [root@localhost ~]# sed '/linux/d' /tmp/test
    HELLO LINUX!  
    
    Linux is a free unix-type opterating system.  
    
    
    Linux test 
    
    [root@localhost ~]# sed '/^Linux/d' /tmp/test   //删除Linux开头的行
    HELLO LINUX!  
    
    
    This is a linux testfile!  
    
  • 删除从第n行到带有word的行(第三行到Linux的行)

    [root@localhost ~]# sed '3,/linux/d' /tmp/test
    HELLO LINUX!  
    
    
    Linux test 
    
  • 删除从有word1行到有word2行(is,linux)

    [root@localhost ~]# sed '/is/,/linux/d' /tmp/test
    HELLO LINUX!  
    
    
    Linux test 
    
  • 删除空白行

    [root@localhost ~]# sed '/^$/d' /tmp/test
    HELLO LINUX!  
    Linux is a free unix-type opterating system.  
    This is a linux testfile!  
    Linux test 
    

地址定界

[root@localhost ~]# cat /tmp/test1
linux
linux linux
linux linux linux
linux linux linux linux
linux
linux
linux
  • 默认替换每行第一个匹配字符

    [root@localhost ~]# sed 's/linux/LINUX/' /tmp/test1
    LINUX
    LINUX linux
    LINUX linux linux
    LINUX linux linux linux
    LINUX
    LINUX
    LINUX
    
  • 全面替换g

    [root@localhost ~]# sed 's/linux/LINUX/g' /tmp/test1
    LINUX
    LINUX LINUX
    LINUX LINUX LINUX
    LINUX LINUX LINUX LINUX
    LINUX
    LINUX
    LINUX
    
  • 替换第n行全部匹配字符(第二行)

    [root@localhost ~]# sed '2s/linux/LINUX/g' /tmp/test1
    linux
    LINUX LINUX
    linux linux linux
    linux linux linux linux
    linux
    linux
    linux
    
  • 替换第n行匹配的第m个字符(第四行第二个字符)

    [root@localhost ~]# sed '4s/linux/LINUX/2' /tmp/test1
    linux
    linux linux
    linux linux linux
    linux LINUX linux linux
    linux
    linux
    linux
    
  • 替换第n行匹配的第m开始到最后一个(第四行第二个字符开始)

    [root@localhost ~]# sed '4s/linux/LINUX/2g' /tmp/test1
    linux
    linux linux
    linux linux linux
    linux LINUX LINUX LINUX
    linux
    linux
    linux
    

已匹配字符串标记:&

  • 正则表达式 \w+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词

    [root@localhost ~]# echo I LOVE LINUX | sed 's/\w\+/[&]/g'
    [I] [LOVE] [LINUX]
    
  • 以192.168.0.1开头的行都会被替换成它自已加localhost

    sed 's/^192.168.0.1/&localhost/' file
    192.168.0.1localhost
    

子串匹配标记:\1

\(..\) 用于匹配子串,对于匹配到的第一个子串就标记为 \1,依此类推匹配到的第二个结果就是 \2

  • 匹配给定样式的其中一部分

    [root@localhost ~]# echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'          \\digit 7被替换成了 7
    this is 7 in a number
    
  • 匹配2个部分

    [root@localhost ~]# echo aaa BBB | sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'
    BBB aaa
    
  • love被标记为1,所有loveable会被替换成lovers

    echo loveable | sed -n 's/\(love\)able/\1rs/p'
    

从文件读入:r命令

  • 读取test1文件的内容,显示在test文件匹配行的后面,如果多行匹配,test1文件内容将显示在所有匹配行的下面

    [root@localhost ~]# sed '/linux/r /tmp/test1' /tmp/test
    HELLO LINUX!  
    
    Linux is a free unix-type opterating system.  
    
    This is a linux testfile!  
    linux
    linux linux
    linux linux linux
    linux linux linux linux
    linux
    linux
    linux
    
    Linux test 
    

在行后追加文本:a\

  • 匹配linux行后插入

    [root@localhost ~]# sed '/linux/a\hello everyone' /tmp/test
    HELLO LINUX!  
    
    Linux is a free unix-type opterating system.  
    
    This is a linux testfile!  
    hello everyone
    
    Linux test 
    
  • 第二行后插入

    [root@localhost ~]# sed '2a\hello everyone' /tmp/test
    HELLO LINUX!  
    
    hello everyone
    Linux is a free unix-type opterating system.  
    
    This is a linux testfile!  
    
    Linux test 
    

在行前追加文本:i\

  • 匹配linux行前插入 [root@localhost ~]# sed '/linux/i\hello everyone' /tmp/test HELLO LINUX!

    Linux is a free unix-type opterating system.  
    
    hello everyone
    This is a linux testfile!  
    
    Linux test 
    [root@localhost ~]# 
    
  • 第二行前插入

    [root@localhost ~]# sed '2i\hello everyone' /tmp/test
    HELLO LINUX!  
    hello everyone
    
    Linux is a free unix-type opterating system.  
    
    This is a linux testfile!  
    
    Linux test 
    

写入文件:w

  • 打开test文件,把匹配的行写入test2文件中,并在屏幕中不输出(-n)

    [root@localhost ~]# sed -n '/linux/w /tmp/test2' /tmp/test
    [root@localhost ~]# cat /tmp/test2
    This is a linux testfile!  
    

高级编辑命令相关实例

覆盖读取匹配到的行的下一行至模式空间中:n

  • 匹配行的下一行,进行替换并输出

    [root@localhost ~]# sed '/linux/{n;s/linux/LINUX/}' /tmp/test1
    linux
    LINUX linux
    linux linux linux
    LINUX linux linux linux
    linux
    LINUX
    linux
    
  • 输出偶数行

    [root@localhost ~]# sed -n 'n;p' /tmp/test1
    linux linux
    linux linux linux linux
    linux
    
  • 显示奇数行;

    [root@localhost ~]# sed 'n;d' /tmp/test3
    HELLO LINUX!
    This is a linux testfile!
    
  • 取出最后一行

    [root@localhost ~]# sed '$!d' /tmp/test3
    Linux test
    
  • 在原有的每行后方添加一个空白行

    [root@localhost ~]# sed 'G' /tmp/test3
    HELLO LINUX!
    
    Linux is a free unix-type opterating system.
    
    This is a linux testfile!
    
    Linux test
    
    [root@localhost ~]# 
    
  • 取出文件后两行

    [root@localhost ~]# sed '$!N;$!D' /tmp/test3
    This is a linux testfile!
    Linux test
    
  • 删除原有的所有空白行,而后为所有的非空白行后添加一个空白行;

    [root@localhost ~]# cat -n /tmp/test
         1  HELLO LINUX!  
         2
         3  Linux is a free unix-type opterating system.  
         4
         5  This is a linux testfile!  
         6
         7  Linux test 
    [root@localhost ~]# sed '/^$/d;G ' /tmp/test | cat -n
         1  HELLO LINUX!  
         2
         3  Linux is a free unix-type opterating system.  
         4
         5  This is a linux testfile!  
         6
         7  Linux test 
         8
    
  • 逆序显示文件的内容

    [root@localhost ~]# cat /tmp/test3
    HELLO LINUX!
    Linux is a free unix-type opterating system.
    This is a linux testfile!
    Linux test
    
    [root@localhost ~]# sed  '1!G;h;$!d' /tmp/test3
    Linux test
    This is a linux testfile!
    Linux is a free unix-type opterating system.
    HELLO LINUX!
    
    
    1!G:如果不是第一行,把保持空间中的内容追加至模式空间中
    h:把模式空间中的内容覆盖至保持空间中
    $!d:如果不是最后一行,删除模式空间中的行
    
    先把保持空间的内容追加到模式空间,在把模式空间的内容覆盖到保持空间,然后删除模式空间的内容

猜你喜欢

转载自blog.csdn.net/eighteenxu/article/details/79802137