sed 命令学习笔记

跳过目录

简介

返回目录
sed是 Stream EDitor 的缩写。完整的介绍sed据说需要一本书。这里只对sed做简单的了解。sed的价值在于,不需要像vim那样打开文件后才能编辑,在shell脚本中,如果要对文本做一些简单的处理(比如插入、删除文本行、替换),可以用sed命令实现。

  • sed命令的执行过程
  • 关于address
  • sed命令支持的常用命令:s、d、p、i、a
  • sed命令的常用选项:-e、-f、-n、-u、-r、-i、–help、–version
  • 重点的 s 命令
  • 命令示例
  • 使用实例

标签:linux,学习笔记

sed 命令的执行过程

返回目录
执行 sed 命令需要告诉 sed 两样东西:sed script和待处理的文本。sed script包含一条或多条sed commandsed 命令)。开始执行后,sed命令一行一行地处理给定的文本,对每一行,依次应用给定的sed命令。

$ echo 'word' | sed 's/hello/world/'
world

这个示例中,word是待处理的文本,只有一行,s/hello/word/是要执行的sed 命令,命令的作用:用word替换hello

sed确定sed script和待处理文本的完整的逻辑是:-e指定sed命令-f指定sed 脚本的文件命名,如果这两个选项都没有,那第一个非sed选项参数被解析为sed 命令。其余非选项参数被人为是待处理的文本文件的名字。如果没有给定待处理的文件名,或这文件名为-,则从标准输入 stdin读取待处理文本。非sed选项参数是指第一个不以-开头的参数。

$ cat tri-hello.txt
1 hello
2 hello
3 hello
$ sed -e 's/hello/world/' tri-hello.txt
1 world
2 world
3 world
# 如果不用 -e 和 -f 选项,第一个非选项参数就是要执行的 sed 命令
$ sed 's/hello/world/' tri-hello.txt
1 world
2 world
3 world
# 用 -e 选项,可以把 sed 命令放在后面,例如:
$ sed  tri-hello.txt  -e 's/hello/world/'
1 world
2 world
3 world
# 如果省略文件名,sed命令会从标准输入获取要处理的文本
$ echo 'word' | sed 's/hello/world/'
world
$ cat tri-hello.txt | sed 's/hello/world/'
1 world
2 world
3 world

处理过程简单描述如下:从input stream中取出一行文本,放入一个叫pattern sapce的地方,把 sed script 里的命令逐个应用到这一行文本上,之后,如果没有指定 -n选项,把pattern space里的内容(就是处理后的文本)输出到output stream中,最后清空pattern space;接着取出下一行文本,继续下一个处理循环。
完整的处理循环参考 gnu 关于 sed 的在线文档中Execution-Cycle部分的内容。

选择要处理的文本行

返回目录
大多数sed命令都可以加上一个address(地址)前缀。省略address的时候,命令会应用在每一行上,指定了address,命令就只在address选定的文本行上起作用。可以把address理解为条件判断,sed命令只处理符合条件的文本行。

最简单的address就是行号,第一个行的编号是 1。

# 最简单的`address`就是行号。行号从 1 开始编号
$ cat tri-hello.txt | sed '1s/hello/----/'
1 ----
2 hello
3 hello
$ cat tri-hello.txt | sed '2s/hello/----/'
1 hello
2 ----
3 hello
$ cat tri-hello.txt | sed '5s/hello/----/'
1 hello
2 hello
3 hello
# 指定行号范围,把“hello”换成“------”
$ cat ten-hello.txt | sed '2,4s/hello/------/'
1 hello
2 ------
3 ------
4 ------
5 hello
6 hello
7 hello
8 hello
9 hello
10 hello

sed的常用命令

返回目录
除了替换命令ssed提供了其它文本处理命令。

command description
p 打印当前行
i 在当前行前面插入文本
a 在当前行后面插入文本
d 删除当前行
s 对当前行作文本替换

命令p

### 测试用的文本,head 命令的 -n 参数在不同的示例中会取不同的值
$ nl /etc/passwd | head -n 5
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
### 命令 p 
# 一般和 -n 选项结合使用,下面的命令打印文件的第3行到第8行
$ nl /etc/passwd | head -n 10 | sed -n '3,7p'
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6  sync:x:5:0:sync:/sbin:/bin/sync
     7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
### 命令 i
# 格式是 i<text>,比如在第一行的前面插入一行内容'hello'
$ nl /etc/passwd | head -n 4 | sed '1ihello'
hello
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
### 命令 a
# 格式是 a<text>,比如在第一行的后面插入一行
$ nl /etc/passwd | head -n4 | sed '1ahello'
     1  root:x:0:0:root:/root:/bin/bash
hello
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
### 命令 d

$ nl /etc/passwd | head | sed '2,5d'
     1  root:x:0:0:root:/root:/bin/bash
     6  sync:x:5:0:sync:/sbin:/bin/sync
     7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     8  halt:x:7:0:halt:/sbin:/sbin/halt
     9  mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    10  news:x:9:13:news:/etc/news:
# 可以看到,2,3,4,5 行都被删除了

命令s是常用命令,所以单列一节,详细学习一下。

替换命令 s

返回目录

  • 替换分隔符可以是任意字符,而不仅仅是/
  • 可以用正则表达式实现复杂的替换
    TODO:完善内容

address的语法

返回目录

Address Description
n A line number where n is a positive integer.
$ The last line.
/regexp/ Lines matching a POSIX basic regular expression. Note that the \regular expression is delimited by slash characters. Optionally, the regular expression may be delimited by an character, by specifying the expression with \cregexpc, where c is the alternate character.
addr1,addr A range of lines from addr1 to addr2, inclusive. Addresses may be any of the single address forms above.
first~step Match the line represented by the number first, then each subsequent line at step intervals. For example 1~2 refers to each odd numbered line, 5~5 refers to the fifth line and every fifth line thereafter.
addr1,+n Match addr1 and the following n lines.
addr! Match all lines except addr, which may be any of the forms above

todo:补充一些演示示例

学习中想到的一些问题

返回目录

  1. sed和其它命令的比较

    可以编写复杂的sed脚本,sed可以实现相当复杂的文本处理任务,但通常只用sed做一些简单的文本处理任务,就是,在命令行中提供一两条简单sed命令,而不是使用复杂的sed脚本

    It is most often used for simple, one-line tasks rather than long scripts.

    sed看作文本处理命令,相关命令有 catsortuniqcutpastejoincommondiffpatchtr

    这些文本处理命令的功能有重合的地方,sed 的用法更复杂,功能也更强大,常见的文本处理任务中,除了文本替换其它任务用别的命令也能实现,而且用起来更简单些。

    1. 输出文件内容:cat命令,或者sed-n选项+p命令
    2. 文本替换
      1. 一般的替换: 只有 seds命令
      2. 大小写转换:tr命令,或者sedy命令
    3. 正则过滤: grep 命令,sedaddress+p命令

    最后,awk是比sed功能更强大的文本处理命令,也更复杂。awk适合处理表格数据。

  2. -e
    第一个非选项参数就是sed 命令,那为什么还要提供-e选项?能去掉-e选项吗?

    1. 加上 -e可以把sed 命令的放在其它位置,而不仅仅是只限定在第一个非选项参数。
    2. -e选项可以出现多次,从而一次性提供多个sed命令
  3. i 和 a 命令
    为什么a和i的功能重复的命令?能去掉其中的一个吗?
    不是完全重复,在第一行前面插入一行文本,用 a 就没法实现;在最后一行的后面插入文本,用 i 就没法实现。

sed的常见任务

返回目录

  1. 取文件 ten-hello.txt 的第 6到第9行的内容。
# 用 sed 命令,
$ sed '6,9p' -n ten-hello.txt
6 hello
7 hello
8 hello
9 hello
# 另一种方式,用 head + tail 命令
$ head -n 9 ten-hello.txt | tail -n $((9-6+1))
6 hello
7 hello
8 hello
9 hello

相关测试文件

生成这些文件的命令

# 生成测试文件
$ nl /etc/passwd | head -n 12 > hp.txt
$ for i in {1..10};do echo $i hello ;done > ten-hello.txt
$ head -n 3 hello.txt > tri-hello.txt

hp.txt 文件内容

返回目录

1  root:x:0:0:root:/root:/bin/bash
2  bin:x:1:1:bin:/bin:/sbin/nologin
3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
4  adm:x:3:4:adm:/var/adm:/sbin/nologin
5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6  sync:x:5:0:sync:/sbin:/bin/sync
7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8  halt:x:7:0:halt:/sbin:/sbin/halt
9  mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10  news:x:9:13:news:/etc/news:
11  uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
12  operator:x:11:0:operator:/root:/sbin/nologin

ten-hello.txt 文件的内容

返回目录

1 hello
2 hello
3 hello
4 hello
5 hello
6 hello
7 hello
8 hello
9 hello
10 hello

参考链接

返回目录

The Linux Command Line
鸟哥的 Linux 私房菜
$ man sed 或者在线手册

猜你喜欢

转载自blog.csdn.net/chenxizhan1995/article/details/89291565