# sed

sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储 在一个命令文本文件中。 sed编辑器会执行下列操作。

  • (1)一次从输入中读取一行数据。
  • (2) 根据所提供的编辑器命令匹配数据。
  • (3) 按照命令修改流中的数据。
  • (4) 将新的数据输出到STDOUT。 在流编辑器将所有命令与一行数据匹配完毕后,它会读取下一行数据并重复这个过程。在流 编辑器处理完流中的所有数据行后,它就会终止。 由于命令是按顺序逐行给出的,sed编辑器只需对数据流进行一遍处理就可以完成编辑操作。 这使得sed编辑器要比交互式编辑器快得多,你可以快速完成对数据的自动修改。

sed命令的格式如下。 sed options script file

  • -e script 在处理输入时,将script中指定的命令添加到已有的命令中
  • -f file 在处理输入时,将file中指定的命令添加到已有的命令中
  • -n 不产生命令输出,使用print命令来完成输出

# s 替换命令

替换命令在替换多行中的文本时能正常工作,但默认情况下它只替换每行中出现的第一处。 要让替换命令能够替换一行中不同地方出现的文本必须使用替换标记(substitution flag)。替换标 记会在替换命令字符串之后设置。

  • 数字,表明新文本将替换第几处模式匹配的地方;
  •  g,表明新文本将会替换所有匹配的文本;
  •  p,表明原先行的内容要打印出来;
  •  w file,将替换的结果写到文件中。

# 案例

  • sed 's/test/trial/' data4.txt
  • sed 's/test/trial/2' data4.txt sed编辑器只替换每行中第二次出现的匹配模式
  • sed -n 's/test/trial/p' data5.txt -n选项将禁止sed编辑器输出。但p替换标记会输出修改过的行。将二者配合使用的效果就是只输出被替换命令修改过的行。
  • sed 's/test/trial/w test.txt' data5.txt
  • sed -e 's/brown/green/; s/dog/cat/' data1.txt
  • sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd 的便捷写法 's!/bin/bash!/bin/csh!' /etc/passwd 在这个例子中,感叹号被用作字符串分隔符,
  • sed '2s/dog/cat/' data1.txt 替换第2行的dog为cat
  • sed '2,5s/dog/cat/' data1.txt替换第2到5行的dog为cat
  • sed '2,$s/dog/cat/' data1.txt 替换第2到后的所有行的dog为cat
  • 如果需要在单行上执行多条命令,可以用花括号将多条命令组合在一起
    • sed '2{
    • s/fox/elephant/
    • s/dog/cat/
    • }' data1.txt

DANGER

两个命令都作用到文件中的每行数据上。命令之间必须用分号隔开,并且在命令末尾和分号 之间不能有空格。

# d 删除命令

  • sed '3d' data6.txt
  • sed '2,3d' data6.txt
  • sed '3,$d' data6.txt
  • sed '/number 1/d' data6.txt

# i 插入 命令

  • echo "Test Line 2" | gsed 'i Test Line 1' 前面插入
  • gsed '3i This is an inserted line.' data6.txt 在第3行前插入

# a 添加 命令

  • echo "Test Line 2" | gsed 'a Test Line 1' 后面增加
  • gsed '3a This is an inserted line.' dat6.txt

# c 修改某行

  • gsed '3c This is an inserted line.' data6.txt 会修改第3行中的文本
  • gsed '/number 3/c This is an inserted line.' data6.txt
  • gsed '2,4c This is an inserted line.' data.txt

# y转换命令

  • sed 'y/123/789/' data8.txt

# -f

script1.sed

s/brown/green/ 
s/fox/elephant/ 
s/dog/cat/
1
2
3

sed -f script1.sed data1.txt

  • sed -n '/number 3/p' data8.txt
  • gsed -n '/another/{p};s/another/linenew/p' data8.txt
  • gsed -n '/another/{p};s/another/linenew/p;w data1.txt' data.txt w输出到data1.txt文件中
  • sed '{2,3b ; s/This is/Is this/ ; s/line./test?/}' data2.txt 分支命令在数据流中的第2行和第3行处跳过了两个替换命令。
  • echo "The cat sleeps in his hat." | sed 's/.at/"&"/g' 当模式匹配了单词cat,"cat"就会出现在了替换后的单词里。当它匹配了单词hat,"hat" 就出现在了替换后的单词中

# 本章需要的文件

data1.txt

The quick brown fox jumps over the lazy dog 
The quick brown fox jumps over the lazy cat 
The quick brown fox jumps over the lazy dog 
The quick brown fox jumps over the lazy dog
1
2
3
4

data4.txt

This is a test of the test script. 
This is the second test of the test script.
1
2

data5.txt

This is a test line. 
This is a different line.
1
2

data6.txt

This is line number 1. 
This is line number 2. 
This is line number 3. 
This is line number 4.
1
2
3
4

data8.txt

This is line number 1. 
This is line number 2. 
This is line number 3. 
This is line number 4. 
This is line number 1 again. 
This is yet another line. 
This is the last line in the file.
1
2
3
4
5
6
7

data9.txt

This line contains tabs.
1