ILD

sed 1
作者:Yuan Jianpeng 邮箱:yuanjp@hust.edu.cn
发布时间:2018-8-17 站点:Inside Linux Development

sed is a stream editor。它对input stream执行基本的文本转换。输入流可以是文件或者pipeline。


2 Running sed


2.1 Overview

通常,sed向下面这样被调用

sed SCRIPT INTPUTFILE ...


例如

sed 's/hello/world/' intput.text > output.txt


如果没有指定INPUTFILE,或者指定为-,sed从标准输入获取内容。


sed将输出写入到标准输出。使用-i选项,来edit files in-place。


默认,sed打印处理过的输出(修改的和删除的不打印)。使用-n选项来抑制这些输出。使用p命令来打印特定的行。

sed -n '45p' file.txt

打印45行。


没有使用-e或者-f选项,sed使用第一个非选项参数作为script,接下来的非选项参数作为输入文件。

如果使用-e或者-f选项,所有的非选项参数,被当做输入文件。


2.2 Command-Line Options


full format for invoking sed:

sed OPTIONS [SCRIPT] [INPUTFILE...]


-n, --quiet, --silent

禁止自动打印,sed只打印p命令显示指定的输出。


-e script, ---expression=script

添加script


-f script-file, --file=script-file

通过脚本文件,添加脚本。


-i[SUFFIX], --in-place[=SUFFIX]

指定files are to be edited in-place,该选项默认开启-s选项。

sed会创建一个临时文件,然后在重命名。没有指定后缀,则重命名为输入文件。否则,重命名为输入文件接一个后缀。但是如果后缀包含*号,则*号,表示文件名。

-ia.*,输入file,输出a.file。


-l N, --line-length=N

指定l命令的line-wrap length,默认为70,0表示绝不wrap long lines。


--posix

不使用sed的扩展


--follow-synlinks

只有在-i选项时,才有效。

指定该选项,sed将编辑最终的文件。否则,break the symbolic link,最终的文件不会被修改。


-E, -r, --regexp-extended

使用extended regular expressions,而不是basic regular expressions。extended regular expressions是egrep接受的正则表达式。


-s, --separate

默认sed,将所有的输入当成一个连续的输入。该命令,指定分开它们。例如行号,在新的文件从0重新开始等。


-u, --unbuffered

尽可能少的buffer 输入和输出。


-z, --null-data, --zero-terminated

行是以零字符结束的。而不是newline。


2.3 Exit status


0 成功完成

1 非法命令,非法语法,非法的正则表达式

2 一个或多个输入文件无法打开

4 I/O错误


除此之外,q或者Q命令,可以指定退出值。


3 sed scripts


3.1 sed script overview


一个sed调用,包含一个或多个sed commands


sed commands 遵循下面的语法

[addr]X[options]


X是单字母的命令。

[addr]是一个可选的行地址。如果指定[addr],命令X只在匹配的行上执行。地址可以是单个行号,可以是正则表达式,也可以是行的范围。

[options]是命令的选项


sed '/^foo/q42' inputfile > output.txt

/^foo/是一个正则表达式地址。如果匹配到foo开头的行,则退出。


script或者script-file中的多个命令,使用 分号 ; 或者 newline \n 分开。

多个script选项指定的命令,自然是分开的。


下面的命令是等价的

1
2
3
4
5
6
7
8
9
10
sed ’/^foo/d ; s/hello/world/’ input.txt > output.txt
 
sed -e ’/^foo/d’ -e ’s/hello/world/’ input.txt > output.txt
 
echo ’/^foo/d’ > script.sed
echo ’s/hello/world/’ >> script.sed
sed -f script.sed input.txt > output.txt
 
echo ’s/hello/world/’ > script2.sed
sed -e ’/^foo/d’ -f script2.sed input.txt > output.txt


命令a, c, i, 由于它们的语法,不能使用分号分开。使用其它技巧来分开。


3.2 sed commands summary


a\textAppend text after a line
a textAppend text after a line (alternative syntax)
b labelBranch unconditionally to label, The label may be omitted, in which case the next cycle is started.

c\

text

Replace (change) lines with text
c textReplace (change) lines with text (alternative syntax)
dDelete the pattern space; immediately start next cycle
D

If pattern space contains newlines, delete text in the pattern space up to the first newline and restart cycle with the resultant pattern space, without reading a new line of input.

If pattern space contains no newline, start a normal new cycle as if the d command was issued.

eExecutes the command that is found in pattern space and replaces the pattern space with the output;  a trailing newline is suppressed.
e commandExecutes command and sends its ouput to the output stream. The command can run across multiple lines, all but the last ending with a back-slash.
F
Print the file name of the current input file (with a trailing newline)
gReplace the contents of the pattern space with the contents of the hold space
GAppend a newline to the contents of the pattern space, and then append the contents of the hold space to that of the pattern space
hReplace the contents of the hold space with the contents of the pattern space
HAppend a newline to the contents of the hold space, and then append the contents of the pattern space to that of hold space

i\

text

insert text before a line
i textinsert text before a line (alternative syntax)
lprint the pattern space in an unambiguous form
nif auto-print is not disabled, print the pattern space, then regardless, replace the pattern space with the next line of input. if there is no more input then sed exits without processing any more commands
NAdd a newline to the pattern space, then append the next line of input to the pattern space. If there is no more input then sed exits without processing any more commands
pprint the pattern space.
Pprint the pattern space, up to the first newline.
q[exit-code]exit sed without processing any more commands or input.
Q[exit-code]this command is the same as q, but will not print the contents of pattern space.
r filenamereads file filename
R filenamequeue a line of filename to be read and insterted into the output stream at the end of the current cycle, or when the next input line is read.
s/regexp/replacement/[flags]Match the regular-expression against the content of the pattern space. If found, replace matched string with replacement
t labelBranch to label only if there has been a successful substitution since the

last input line was read or conditional branch was taken. The label may be

omitted, in which case the next cycle is started.

T label

Branch to label only if there have been no successful substitutions since

the last input line was read or conditional branch was taken. The label may be omitted, in which case the next cycle is started.

v [version]

This command does nothing, but makes sed fail if GNU sed extensions

are not supported, or if the requested version is not available.

w filenamewrite the pattern space to filename
W filenamewrite to the given filename the portion of the pattern space up to the first newline
x
exchange the contents of the hold and pattern spaces.
y/src/dst/Transliterate any characters in the pattern space which match any of the source-chars with the corresponding character in dest-chars.
zempties the content of pattern space
#a commet until the next newline
{ cmd ; cmd ... }group several commands together
=print the current input line number (with a trailing newline)
: label
specify the location of label for branch commands (b, t, T)


3.3 The s Commands


语法

s/regexp/replacement/flags


匹配pattern space和regexp,匹配的部分被替换为replacement。replacement可以包含\1 \2等,对匹配结果的引用。replacement可以包含未转义的&,表示整个匹配的部分。


命令中,分割符 / 可以替换为任何其它单个字符。分隔符,在regexp和repalcement使用反斜杠转义。


GNU sed扩展,可以再replacement中包含下述特殊序列

\L 接下来的字符变成小写,直到\U或者\E被发现

\l 下一个字符变成小写

\U 接下来的字符变成大写,知道\L或者\E被发现

\u 下一个字符变成大写

\E 停止大小写转换。


例子

s/\(b\?\)-/x\u\1/g

将匹配的内容的第一个字符变成大写。


支持下列flags

g

应用所有匹配的替换,而不是第一个。这是对次来说的。


number

只应用n次匹配


p

如果有匹配,则打印新的pattern space。默认会打印。和-n结合使用很用意义。


w filename

如果有匹配,将新的pattern space写到filename指定的文件。


e

新的pattern space被当成命令,执行后,并用输出结果替换pattern space.


I, i

case-insensitive


M, m

M 指定 multi-line mode,多行模式下,^ $ 匹配新行后面和前面的empty string。

\‘ 和 \’ 匹配 buffer和开头和结尾

点号不匹配新行


3.4 Often-Used commands


# [No addresses allowed]

开始一个注释。如果以 #n 开头,则被当做是 -n 选项。


-q [exit-code]

如果没有使用-n选项,则退出行也会被打印。


d

删除当前行,立即开始下一个cycle


p

打印pattern space,通常和-n结合使用


n

如果auto-print没有disabled,打印pattern space,然后使用下一行替换pattern space,继续执行后面的命令。例如,没3行执行一次替换

seq 6 | sed 'n;n;s/./x/'


{ commands }

组合一个命令,通常用来共享一个地址,如

seq 3 | sed -n '2{s/2/X; p}'


3.8 Multiple commands syntax


有几种方法可以指定多个命令。当使用文件来存储sed script时,新行是最自然的方法。


在命令行,可以用下面的方法指定新行:

1
2
3
4
5
6
seq 6 | sed '1d
> 3d'
2
4
5
6


使用分号; 也可以。

1
2
3
4
5
seq 6 | sed '1d;3d'
2
4
5
6


b, t, T, : 4个命令的labels,会一直都到分号。开头和结尾的空白被忽略。


使用多个-e选项也是方法

1
2
3
4
5
seq 6 | sed -e 1d -e 3d
2
4
5
6


3.8.1 Commands Requiring a newline


下面的命令不能使用分号分开,而要使用新行。


a,c,i (append,change,insert)

这3个命令后面的所有文本都被当做要追加,改变和插入的文本,直到新行。


# (comment)

r, R, w, W

e (command excution)

s///[we] (substitute with e or w flags)


参考

sed manual


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.