文本三剑客之sed详解

一. sed简介

 sed全名为stream editor,六编辑器,用程序的方式来编辑文本,功能十分强大
sed是一种分交互式编辑器,它使用预先设定好的编辑指令对输入的文本进行编辑,完成后再输出编辑结构.sed基本上都是使用正则表达式进行模式比配

二. sed的工作原理

 sed会一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区,形成”模式空间”,接着用sed命令处理缓冲区中的内容,处理结束后,把缓冲区的内容送往屏幕.接着处理下一行的内容,这样不断重复,直至文件末尾.文件内容并没有发生改变,除非使用重定向存储输出

三. sed的基本语法

 sed [选项] `command` 文件名称

 常用选项包括:  -n,-e,-i,-f,-r

 command包括: [地址1, 地址2] [函数] [参数(标记)]

四. 常用选项

  • -n: 取消打印到屏幕

sed默认会把模式空间处理完毕后的内容输出到标准输出,也就是输出到屏幕上,加上-n选项后被设定为安静模式,也就是不会输出默认打印信息,除非子命令中特别指定打印选项,则只会把匹配修改的行进行打印。

1.
    echo -e 'hello world\nnihao' | sed 's/hello/A/'
    结果:
        A world
        nihao
例2.
    echo -e 'hello world\nnihao' | sed -n 's/hello/A/'
    结果:加-n选项后什么也没有显示。
例3.
    echo -e 'hello world\nnihao' | sed -n 's/hello/A/p'
    结果:A world/
    说明:-n选项后,再加p标记,只会把匹配并修改的内容打印了出来。
  • -i 保存编辑内容至源文件
1.
    cat file.txt
    结果: hello world
    sed '/s/hello/A' file.txt
    结果: A world
    cat file.txt
    结果: hello world
例2.
    sed -i '/s/hello/A' file.txt
    cat file.txt
    结果: A world
例3. 备份源文件
    sed i.bak 's/hello/A/' file.txt
    ls
    结果: file.txt  file.txt.bak
  • -e: 多点编辑,表示且关系
    如果需要用sed对文本内容进行多种操作,则需要执行多条子命令来进行操作。
1.
    echo -e 'hello world' | sed -e 's/hello/A/' -e 's/world/B/'
    结果: A B
例2.
    echo -e 'hello world' | sed -e 's/hello/A/;s/world/B/'
    结果: A B
  • -f: 从指定文本中读取编辑脚本的sed语句
    vim sed.script    # 在脚本文件中的子命令串就不需要输入单引号了
     s/hello/A/
     s/world/B/
    echo "hello world" | sed -f sed.script
    结果:A B
  • -r: 支持使用扩展正则表达式
    sed命令的匹配模式支持正则表达式的,默认只能支持基本正则表达式,如果需要支持扩展正则表达式,那么需要添加-r选项。
echo "hello world" | sed -r 's/(hello)|(world)/A/g'
结果: A A

五.地址定界

  1. 定址概念
    默认情况下会对文本的每一行内容进行匹配,处理,输出,但如果我们只需文本的某些部分,就可使用定位特定的行还处理,这个定位指定的行的行为就叫"定址"

  2. 数字定址
    数字定址就是指定具体的行去编辑,数字定址有几种方法

1. 将文本的第4行的hello字符串替换成A,其他方不会被替换
    sed -n '4s/hello/A/' message

例2. 将文本的2-4行的hello字符串替换成A 
    sed -n '2,4s/hello/A/' message

例3. 从文本的第2行开始往下数4行,也就是2-6行中的hello替换成A
    sed -n '2,+4s/hello/A/' message

例4.从第4行开始,每隔3行就减hello替换成A
     sed -n '4~3/hello/A/' message

例5. $表示最后一行 !表示相反的行数
    sed -n '$s/hello/A/' message    #匹配最后一行
    sed -n "1!s/hello/A/" message   #除了第一行  

3.正则定址
正则定址是通过正则表达式来匹配编辑内容所在行

1. 将匹配到的行删除
    sed -n '/hello/d'   message2. 删除空行
    sed -n '/^$/d' message3. 删除以TS开头到TE开头之间的行
    sed -n '/^TS,/TE/d' message
  1. 数字定址和正则定址的混用
例. 删除从第1行到以TS开头的行之间的内容
    sed -n '/1,/^TS/d' message
  1. 定址的分组
1
    vim sed.script
        /^TS,/TE/{       # 匹配TS开头的行到TE开头的行之间的内容
        s/CN/China/      # CN替换成China
        s/Beijing/BJ/    # Beijing 替换成 BJ
        }
    sed -f sed.script message  
例2
    sed -n '2,4s{/cn/china/;/a/b/}' message

六 sed的基本子命令

  1. 子命令a:表示在指定行下插入指定内容,以空格做分界线
1:将message文件中每一行下边都插入添加一行内容是A。
    sed 'a A' message

例2:将message文件中1-2行的下边插入添加一行内容是A
    sed '1,2a A' message

例3:将message文件中1-2行的下边分别添加3行,3行内容分别是A、B、C,
    sed '1,2a A\nB\nC' message

2.子命令i:在指定行上边插入指定行的内容

1:将message文件中每一行上边都插入添加一行内容是A
    sed '/i A' message2:将message文件中1-2行的上边插入添加一行内容是A
    sed '/1,2i A' message3:将message文件中1-2行的上边分别添加3行,3行内容分别是A、B、C
    sed '/1,2i A\nB\nC' message

3.子命令c:把指定的行内容替换为自己需要的行内容

1:将message文件中所有的行内容都分别替换为A行内容。
    sed 'c A' message2:将message文件中1-2行的内容替换为A,只替换成一个A
    sed '1,2c A' message3:将message1-2行内容分别替换为了A
    sed '1,2c A\nA' message

4.子命令d:表示删除指定的行内容

1:删除message内的所有行
    sed 'd' message2:删除message内的1-3行
    sed '1,3d' message

5.子命令y:字符替换,可替换多个字符,却不可以替换字符串且不支持正则表达式

例子:把message中所有a字符替换为A符号,所有b字符替换为B符号。
    sed 'y/ab/AB' message
强调一下,这里的替换源字符个数和目的字符个数必须相等;

6.子命令=:在指定行的上边显示行号

例:打印12的行号
    sed '1,2=' message

7.子命令r:将内容追加到指定行的下边

例:将a.txt文件内容读取并插入到message文件第2行的下边
    sed '2r a.txt' message

8.子命令s:字符串替换,支持正则表达式
基本语法:
【address】s / pattern / replacememt / flags
s字符串替换,替换的时候可以把/换成其他的符号,比如 =
replacement:

 &: 用正则表达式匹配的内容进行替换
 \n:回调参数
 \(\): 保存被匹配的字符一杯反向引用 \n时使用

Flags:

n:可以是1-512,表示第n次出现的情况进行替换
g:全局更改
p:打印模式空间的内容
w file:写入到一个文件的file

实战用法:
测试文件:

# cat message
hello 123 world
1:将message每行包含的第一个hello的字符串替换为HELLO
    sed 's/hello/HELLO/' message
    结果:HELLO 123 world

例2:使用扩展正则表达式匹配内容,将匹配到的内容替换成A
    sed -r 's/[a-z]+ [0-9]+ [a-z]+/A/' message
    结果: A3:使用正则分组功能,\1表示第一个分组,\2表示第二个分组,\3表示第三个分组
    sed -r 's/([a-z]+ ) ([0-9]+) ([a-z]+ /\3\2\1/)' message
    结果: world 123 hello

例4:使用&功能,代表整个匹配结果,111&222,表示将整个结果插入111 222之间
    sed -r 's/([a-z]+ ) ([0-9]+) ([a-z]+)/&/ '  



你可能感兴趣的:(linux)