Sed 速查表

sed 语法

sed [options]... [script] [input-file]

sed 默认输入输出为 stdin, stdout

sed treats multiple input files as one long stream. The following example prints the first line of the first file (one.txt) and the last line of the last file (three.txt). Use -s to reverse this behavior.
下面的命令中, sed 将 one two three 三个文件当作一个输入, 所以只会输出 one文件的第一行和 three 文件的最后一行

sed -n '1p ; $p' one.txt two.txt three.txt

options

-n
--quiet

By default sed prints all processed input (except input that has been modified/deleted by commands such as d). Use -n to suppress output, and the p command to print specific lines. The following command prints only line 45 of the input file:

-i
--in-place

修改文件并备份原文件

sed -i.bak 's/foo/bar/g' file.txt等于```sed –in-place=.bak ’s/foo/bar/g' file.txt`

以上命令会修改 file.txt 文件的内容, 并且备份原文件为 file.txt.bak

sed -i 's/foo/bar/g' file.txt 则会直接修改 file.txt 文件

1
2
3
4
5
6
7
8
# 从文件中读取脚本
sed -f myscript.sed input.txt
# -e 指定脚本, 通常可省略
sed 's/hello/world/' input.txt
sed -e 's/hello/world/' input.txt
sed --expression='s/hello/world/' input.txt
# -e 参数可以连续使用
sed -e '/^foo/d' -e 's/hello/world/' input.txt

-s
--separate

上面提到过, sed会将多个文件合并成一个输入, 使用-s命令可以将它们拆分视为多个输入

script 语法

[addr]X[options]

X 表示一个sed 命令字母

[addr]

addr 表示行地址, 可以是行号, 正则表达式, 也可以是地址范围

行号

sed '144s/hello/world/' input.txt

将第144行的hello替换成world

$ 表示最后一行

n~step

第n行开始的每隔step行

1
2
3
4
5
6
7
8
9
seq 10 | sed -n '0~4p'
4
8

seq 10 | sed -n '1~3p'
1
4
7
10

正则表达式 /regexp/

sed '/apple/s/hello/world/' input.txt 将包含apple的行 的hello 替换成 world

如果要匹配的字符串本身包含 斜杠/, 可以用其他符号代替斜杠(通常是%), 这样可以避免频繁使用 \ 来转义 /

下面三种写法都是匹配 以/home/alice/documents/开头的行

1
2
3
sed -n '/^\/home\/alice\/documents\//p'
sed -n '\%^/home/alice/documents/%p'
sed -n '\;^/home/alice/documents/;p'

/regexp/M 多行匹配模式

地址范围

addr1, +N

匹配第addr1行及后面的N行

1
2
3
4
seq 10 | sed -n '6,+2p'
6
7
8

sed '4,17s/hello/world/' input.txt 从第4行到第17行的hello 替换成world(左闭右闭)

! 反向匹配
sed '/apple/!s/hello/world/' input.txt不包含apple的行 的hello 替换成 world

地址范围
sed '4,17s/hello/world/' input.txt 将除了从第4行到第17行的所有行的hello 替换成world

commands(X)

a (在addr后面添加内容)

1
2
3
4
5
    seq 3 | sed '2a hello'
    1
    2
    hello
    3

i (在addr前面插入内容)

c (替换addr整行内容)

1
2
3
4
seq 10 | sed '2,9c hello'
1
hello
10

p (输出addr行的内容, 配合-n使用)

y/src/dst/ (映射替换)

1
2
echo hello world | sed 'y/abcdefghij/0123456789/'
# 74llo worl3

s/regexp/replacement/[flags] (替换文本)

[flags]
  • g, 全局匹配

  • [number], 仅替换第n个匹配的字符串


examples

以下的替换、追加及删除操作, 是不会修改原文件的, 修改文件需要加上-i参数

查找

sed -n '/hello/p' file.txt

修改文件并备份原文件

sed -i.bak 's/foo/bar/g' file.txt

以上命令会直接修改 file.txt 文件的内容, 并且备份原文件为 file.txt.bak

-i 的意思是 inplace

替换文本

1
2
3
sed 's/old/new/g' file.txt
# s 表示执行替换操作
# g 表示全局替换

追加行

1
2
3
4
5
6
7
8
9
sed '$a THE END!' file.txt
# $ 表示最后一行
# a 表示追加行
# 'THE END' 表示 要追加内容
# 并不会修改 file.txt 中的内容, 如果
sed '2 i new-line' input.txt
# 在第二行前面插入 'new-line'
sed '2 a new-line' input.txt
# 在第二行前面插入 'new-line'

删除行

删除第5到7行

1
sed '5,7d' file.txt

删除第5行和第7行

1
sed '5d;7d' file.txt
1
2
# 删除 'Hello' 开头的所有行, 区分大小写
sed '/^Hello/d' file.txt

sed, a stream editor

linux - The Concept of ‘Hold space’ and ‘Pattern space’ in sed - Stack Overflow