我们先简单了解下 sed

开始

准备数据

1
2
3
4
5
6
7
8
9
10
$ cat > test << "EOF"
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam
EOF

替换

1
2
3
4
5
6
7
8
9
$ sed 's/This/That/g' test
That is my cat
my cat's name is betty
That is my dog
my dog's name is frank
That is my fish
my fish's name is george
That is my goat
my goat's name is adam

我们将每行输出的 This 替换为 That,sed 默认输出是将修改的文件输出到屏幕上,如果想要修改原文件,则需要加上 -i 参数

1
$ sed -i 's/This/That/g' test

修改原文件的命令需要在 Linux 中运行,Mac 中略有不同。

原则上这个操作习惯并不好,安全的方式是将输出的结果通过管道输入到另一个文件中

1
$ sed 's/This/That/g' test > test1

动作

从上面的简单例子,可以得到 sed 的语法为

1
$ sed [参数] <动作> [file]

动作规则为:n1,n2 action args

n1,n2 为执行动作的行数范围,不是必传

action 取值为:

  • a:新增,a 的后面可以接字符串,而这些字符串会在新的一行出现(目前的下一行)。
  • c:替换,c 的后面可以接字符串,这些字符串可以替换n1,n2之间的行!
  • d:删除,因为是删除,所以 d 后面通常不接任何参数。
  • i:插入,i 的后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行)。
  • p:打印,也就是将某个选择的数据打印出来,通常 p 会与参数 sed -n 一起运行。
  • s:替换,可以直接进行替换工作。通常这个 s 的动作可以匹配正则表达式!

s 替换

s 刚才有过例子,它支持正则匹配的方式对文本进行替换,先了解一点正则的知识

  • ^ 表示一行的开头。如:/^#/ 以#开头的匹配。
  • $ 表示一行的结尾。如:/}$/ 以}结尾的匹配。
  • \< 表示词首。 如:\<abc 表示以 abc 为首的詞。
  • > 表示词尾。 如:abc> 表示以 abc 結尾的詞。
  • . 表示任何单个字符。
  • * 表示某个字符出现了0次或多次。
  • [ ] 字符集合。 如:[abc] 表示匹配a或b或c,还有 [a-zA-Z] 表示匹配所有的26个字符。如果其中有^表示反,如 [^a] 表示非a的字符

举几个最常用的例子

行开头添加字符

1
2
3
4
5
6
7
8
9
10
$ sed 's/^/# /g' test

# This is my cat
# my cat's name is betty
# This is my dog
# my dog's name is frank
# This is my fish
# my fish's name is george
# This is my goat
# my goat's name is adam

行尾添加字符

1
2
3
4
5
6
7
8
9
10
$ sed 's/$/  ----/g' test

This is my cat ----
my cat's name is betty ----
This is my dog ----
my dog's name is frank ----
This is my fish ----
my fish's name is george ----
This is my goat ----
my goat's name is adam ----

替换指定行

1
2
3
4
5
6
7
8
9
10
$ sed '3s/my/your/g' test

This is my cat
my cat's name is betty
This is your dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam

替换范围行

1
2
3
4
5
6
7
8
9
10
$ sed  '3,5s/my/your/g'  test

This is my cat
my cat's name is betty
This is your dog
your dog's name is frank
This is your fish
my fish's name is george
This is my goat
my goat's name is adam

替换每行的第 n 个匹配项

1
2
3
4
5
6
7
8
9
10
$ sed  's/s/S/2'  test

This iS my cat
my cat's name iS betty
This iS my dog
my dog's name iS frank
This iS my fish
my fish'S name is george
This iS my goat
my goat's name iS adam

替换多个匹配规则

1
2
3
4
5
6
7
8
9
10
$ sed  's/my/your/g; s/is/Is/g'  test

ThIs Is your cat
your cat's name Is betty
ThIs Is your dog
your dog's name Is frank
ThIs Is your fIsh
your fIsh's name Is george
ThIs Is your goat
your goat's name Is adam

或者使用参数 -e

1
$ sed -e 's/my/your/g' -e 's/is/Is/g'  test

匹配项作为变量

使用 & 作为匹配项的变量,可以在变量旁边加上符号等

1
2
3
4
5
6
7
8
9
10
$ sed 's/my/[&]/g'  test

This is [my] cat
[my] cat's name is betty
This is [my] dog
[my] dog's name is frank
This is [my] fish
[my] fish's name is george
This is [my] goat
[my] goat's name is adam

奇数行替换

1
2
3
4
5
6
7
8
9
10
$ sed 'N;s/my/your/' test

This is your cat
my cat's name is betty
This is your dog
my dog's name is frank
This is your fish
my fish's name is george
This is your goat
my goat's name is adam
1
2
3
4
5
$ sed 'N;s/\n/,/' test
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam

i 插入

i 可以在某一行前面插入数据

在第二行前加入

1
2
3
4
5
6
7
8
9
10
11
$ sed  '2 i ---------------' test

This is my cat
---------------
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam

在第一和第二行插入

1
2
3
4
5
6
7
8
9
10
11
$ sed  '1,2 i ---------------' test
---------------
This is my cat
---------------
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam

匹配指定字符行插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ sed '/my/ i -------' test

-------
This is my cat
-------
my cat's name is betty
-------
This is my dog
-------
my dog's name is frank
-------
This is my fish
-------
my fish's name is george
-------
This is my goat
-------
my goat's name is adam

a 新增

a 在某一行后面新增数据

1
2
3
4
5
6
7
8
9
10
11
$ sed  '2 a ---------------' test

This is my cat
my cat's name is betty
---------------
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam

c 替换

c 的替换是正行的替换

1
2
3
4
5
6
7
8
9
10
$ sed  '2 c My name is wxnacy' test

This is my cat
My name is wxnacy
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam

在运行该命令时,结果可能会不明显,因为 sed 默认是将最终的文本全部输出,我们也可以加上 -n 参数只输出修改行

1
2
$ sed -n '2 c My name is wxnacy' test
My name is wxnacy

d 删除

d 可以删除指定或匹配行

1
2
3
4
5
6
7
8
9
$ sed '1 d' test

my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam
1
2
3
4
5
6
7
$ sed '/dog/ d' test
This is my cat
my cat's name is betty
This is my fish
my fish's name is george
This is my goat
my goat's name is adam
1
2
3
$ sed '3,$ d' test
This is my cat
my cat's name is betty

p 打印

p 可以将匹配行打印出来,可以理解为 grep 命令

1
2
$ sed -n '2 p' test
my cat's name is betty
1
2
3
4
5
6
7
$ sed -n '2,/goat/ p' test
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat

参数文章

03-16 22:33