4

Sed 简明教程和参考 - 基础篇 | UniFreak’s blog

 2 years ago
source link: http://unifreak.github.io/note/sed-tutorial-and-reference-basic
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Sed 简明教程和参考 - 基础篇

  • shell

posted on 13 Apr 2021 under category note

本文内容总结自书籍 Linux 命令行与 shell 脚本编程大全

Sed: Stream EDitor

流编辑器, 区别于交互式编辑器, 通过预先提供的规则编辑数据流. 流编辑器要比交互式编辑器快得多.

Sed 默认不会修改文件数据, 只是发送到 STDOUT.

调用 sed

格式: sed <选项> <命令> <文件>. sed 命令应放到单引号中.

<选项> 可为以下:

  • -i 就地编辑
  • -e script 将 script 中指定的命令添加到已有命令中
  • -f file 将 file 中的命令添加到已有命令中 -f 选项可以指定命令文件, 文件中的命令不用分号, 文件一般命名为 .sed 后缀
  • -n 抑制输出, 使用 print 命令来完成输出
$ echo "This is a test" | sed 's/test/big test/'
This is a big test

$ cat data.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$ sed 's/dog/cat' data.txt
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
$ cat data.txt # sed 默认不会更改原文件内容
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.

# 使用 -e 指定多条命令
# 如果写到一行, 使用 ; 分割命令
$ sed -e 's/brown/green/; s/dog/cat/' data.txt
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
# 也可以写到多行, 此时可以省略 ;. 但注意必须在封尾单引号所在行结束命令
$ sed -e '
> s/brown/green/
> s/fox/elephant/
> s/dog/cat' data.txt
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.

# 使用 -f 指定文件, 运行其中的命令
$ cat script.sed
s/brown/green/
s/fox/elephant/
s/dog/cat
$ sed -f script.sed data.txt
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.

sed 命令默认作用于所有文本行, 可使用两种形式的行寻址指定行:

  • 使用数字指定行: 如单行 2, 区间 2,4, 到尾行 2,$
  • 使用文本模式过滤器指定行: 如单行 /pattern/cmd, 区间 /start_pattern/,/end_pattern/cmd, sed 只支持 BRE.

以上两种指定形式, 可用于单个命令或命令分组:

  • 应用于单个命令: [address]cmd
  • 应用于命令分组时, 注意必须在 { 后换行, 在 } 前换行, 若多个命令在同一行, 可用 ; 分割

      addres {
          cmd1
          cmd2
          ...
      }
    

格式: [address]s/pattern/replacement/flags.

分隔符如果是 / 的话, 必须适时对 / 转义. 如文件路径: sed s/\bin\/bash/\/bin\/csh/ /etc/passwd. 这样比较麻烦. 可以使用除了 / 之外的其他字符作为分隔符, 如使用 !: s!/bin/bash!/bin/csh!.

flags 可为:

  • 数字 指定替换第几个匹配. 认只替换每行第一次出现的匹配.
  • g 替换所有匹配
  • p 打印原行, 通常配合 -n 选项, 以只输出替换过的行
  • w file 写入替换后行到文件中

格式: [address]d

  • 删除全部: d
  • 单行: 3d
  • 区间: 2,3d, 2,$d
  • 模式匹配: /pattern/d
  • 模式匹配区间: /begin_pattern/,/end_pattern/d 每次匹配了 begin_pattern, 就会开始删除

插入/追加/修改

注意, 如果_在命令行中_使用这些命令, 必须在 \ 之后另起一行指定要插入(追加)的内容. 如果要插入(附加)多行文本, 必须在每一个指定文本后使用 \. 最后一行不用.

# 插入命令: i
sed '[address]i\
new line\
multiple line
'

# 追加命令: a
sed '[address]a\
new line
'

# 修改命令: c
sed '[address]c\
new line
'

格式: y/inchars/outchars/

这是唯一一个处理单个字符的命令, 它对 incharsoutchars 的值进行一对一映射. 如果两者长度不同, 会产生一条错误消息. 这个命令 无法限定地址.

p: 打印文本行, 常用于配合 -n 打印出匹配行.

# 打印匹配 number 3 的行
$ sed -n 'number 3/p' data.txt

# 打印 2 和 3 行
$ sed -n '2,3p' data.txt

# 打印原行, 和替换之后的行
$ sed -n '/3/{
> p
> s/line/text/p
> }' data.txt

=: 打印行号

# 打印每一行行号
$ sed '=' data.txt
1
The quick brown fox jumps over the lazy dog.
2
The quick brown fox jumps over the lazy dog.

# 只打印匹配 number 4 的行号和内容
$ sed -n '/number 4/{
> =
> p
> }' data1.txt

l 打印不可打印字符. 要么打印为 \八进制, 要么打印为 C 风格命名法如 \t

$ cat data9.txt
This    line    contains        tabs.
$ sed -n 'l' data9.txt
This\tline\tcontains\t\ttabs.$

格式: [address]w file

# 将 data6.txt 前两行打印到 test.txt 文件中
$ sed '1,2w test.txt' data6.txt
# 将匹配 Browncoat 的行打印到 Browncoats.txt 中
$ sed -n '/Browncoat/w Browncoats.txt' data1.txt

格式: [address]r file. 读取命令允许将一个独立文件中的数据插入到数据流的指定位置后.

$ cat data.txt
This is an added line.
$ cat data1.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.

# 将 data.txt 中行插入到数据流第 3 行后
$ sed '3r data12.txt' data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is an added line.
This is line number 4.

# 将 data.txt 中行插入到数据流匹配 /number 2/ 的行后
$ sed '/number 2/r data.txt' data1.txt
This is line number 1.
This is line number 2.
This is and added line.
This is line number 3.
This is line number 4.

# 将 data.txt 中行插入到数据流末尾
$ sed '$r data.txt' data1.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is an added line.

# 配合删除命令, 实现占位套用. 将模板 notice.std 中 LIST 替换为名单
$ cat notice.std
Would the following people:
LIST
please report to the ship's captain.
$ cat list.txt
Blum, R         Browncoat
McGuiness, A    Alliance

$ sed '/LIST/{
r list.txt
d
}' notice.std
Would the following people:
Blum, R         Browncoat
McGuiness, A    Alliance
please report to the ship's captain.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK