sed 编辑器被称作流编辑器(stream editor),与普通的交互式文本编辑器截然不同。在交互式文本编辑器(比如 Vim)中, 可以用键盘命令交互式地插入、删除或替换文本数据。流编辑器则是根据事先设计好的一组规则编辑数据流。
sed 编辑器根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么保存在命令文本文件中。 sed 编辑器可以执行下列操作:
在流编辑器匹配并针对一行数据执行所有命令之后,会读取下一行数据并重复这个过程。在流编辑器处理完数据流中的所有行后,就结束运行。由于命令是按顺序逐行执行的,因此 sed 编辑器只需对数据流处理一遍(one pass through)即可完成编辑操作。
sed 命令的格式如下:
sed options script file
sed 命令选项:
选项 | 描述 |
---|---|
-e commands | 在处理输入时,加入额外的 sed 命令 |
-f file | 在处理输入时,将 file 中指定的命令添加到已有的命令中 |
-n | 不产生命令输出,使用 p(print)命令完成输出 |
在命令行中定义编辑器命令
$ echo "This is a test" | sed 's/test/big test/'
This is a big test
$ sed 's/dog/cat/' data1.txt
在命令行中使用多个编辑器命令
$ sed -e 's/brown/red/; s/dog/cat/' data1.txt
$ sed -e '
> s/brown/green/
> s/fox/toad/
> s/dog/cat/' data1.txt
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
The quick green toad jumps over the lazy cat.
$
从文件中读取编辑器命令
$ cat script1.sed
s/brown/green/
s/fox/toad/
s/dog/cat/
$ sed -f script1.sed data1.txt
并不是所有的发行版中都默认安装了gawk。
gawk 是 Unix 中最初的 awk 的 GNU 版本。 gawk 比 sed 的流编辑提升了一个“段位”,它提供了一种编程语言,而不仅仅是编辑器命令。在 gawk 编程语言中,可以实现以下操作:
gawk 的报告生成能力多用于从大文本文件中提取数据并将其格式化成可读性报告。最完美的应用案例是格式化日志文件。在日志文件中找出错误行可不是一件容易事。 gawk 能够从日志文件中过滤出所需的数据,将其格式化,以便让重要的数据更易于阅读。
gawk 的基本格式如下。
gawk options program file
gawk 选项
选项 | 描述 |
---|---|
-F fs | 指定行中划分数据字段的字段分隔符 |
-f file | 从指定文件中读取 gawk 脚本代码 |
-v var=value | 定义 gawk 脚本中的变量及其默认值 |
-L [keyword] | 指定 gawk 的兼容模式或警告级别 |
gawk 的强大之处在于脚本。可以编写脚本来读取文本行中的数据,然后对其进行处理并显示,形成各种输出报告。
从命令行读取 gawk 脚本
$ gawk '{print "Hello World!"}'
使用数据字段变量
$ cat data2.txt
One line of test text.
Two lines of test text.
Three lines of test text.
$
$ gawk '{print $1}' data2.txt
One
Two
Three
$
$ gawk -F: '{print $1}' /etc/passwd
在脚本中使用多条命令
$ echo "My name is Rich" | gawk '{$4="Christine"; print $0}'
My name is Christine
$
$ gawk '{
> $4="Christine "
> print $0 }'
My name is Rich
My name is Christine
从文件中读取脚本
$ cat script2.gawk
{print $1 "'s home directory is " $6}
$
$ gawk -F: -f script2.gawk /etc/passwd
root's home directory is /root
...
$ cat script3.gawk
{
text = "'s home directory is "
print $1 text $6
}
$
在处理数据前运行脚本
$ gawk 'BEGIN {print "Hello World!"}'
Hello World!
$
$ cat data3.txt
Line 1
Line 2
Line 3
$
$ gawk 'BEGIN {print "The data3 File Contents:"}
> {print $0}' data3.txt
The data3 File Contents:
Line 1
Line 2
Line 3
$
在处理数据后运行脚本
$ gawk 'BEGIN {print "The data3 File Contents:"}
> {print $0}
> END {print "End of File"}' data3.txt
The data3 File Contents:
Line 1
Line 2
Line 3
End of File
$
整合在一起,从一个简单的数据文件中创建一份完整的报告:
$ cat script4.gawk
BEGIN {
print "The latest list of users and shells"
print "UserID \t Shell"
print "------- \t -------"
FS=":"
}
{
print $1 " \t " $7
}
END {
print "This concludes the listing"
}
$
$ gawk -f script4.gawk /etc/passwd
The latest list of users and shells
UserID Shell
-------- -------
root /bin/bash
daemon /usr/sbin/nologin
[...]
christine /bin/bash
sshd /usr/sbin/nologin
This concludes the listing
$
s/pattern/replacement/flags
$ cat data5.txt
This is a test line.
This is a different line.
$
$ sed -n 's/test/trial/p' data5.txt
This is a trial line.
$
$ sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd
$ sed 's!/bin/bash!/bin/csh!' /etc/passwd
[address]command
address {
command1
command2
command3
}
$ sed '2s/dog/cat/' data1.txt // 只修改了地址所指定的第二行的文本。
$ sed '2,3s/dog/cat/' data1.txt // 使用了行区间(第2行-第3行)
$ sed '2,$s/dog/cat/' data1.txt // 将命令应用于从某行开始到结尾的所有行,可以使用美元符号作为结尾行号
/pattern/command
$ grep /bin/bash /etc/passwd
root:x:0:0:root:/root:/bin/bash
christine:x:1001:1001::/home/christine:/bin/bash
rich:x:1002:1002::/home/rich:/bin/bash
$
$ sed '/rich/s/bash/csh/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
[...]
christine:x:1001:1001::/home/christine:/bin/bash
sshd:x:126:65534::/run/sshd:/usr/sbin/nologin
rich:x:1002:1002::/home/rich:/bin/csh
$
$ sed '2{
> s/fox/toad/
> s/dog/cat/
> }' data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown toad jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$
$ sed '3,${
> s/brown/green/
> s/fox/toad/
> s/lazy/sleeping/
> }' data1.txt
$ sed 'd' data1.txt
$ cat data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
$ sed '3d' data6.txt
This is line number 1.
This is line number 2.
This is the 4th line.
$ sed '2,3d' data6.txt
This is line number 1.
This is the 4th line.
$ sed '3,$d' data6.txt
This is line number 1
This is line number 2.
$ sed '/number 1/d' data6.txt
This is line number 2.
This is the 3rd line.
This is the 4th line.
$
$ sed '/1/,/3/d' data6.txt
This is the 4th line.
$
$ cat data7.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
This is line number 1 again; we want to keep it.
This is more text we want to keep.
Last line in the file; we want to keep it.
$
$ sed '/1/,/3/d' data7.txt
This is the 4th line.
$
sed '[address]command\
new line '
$ echo "Test Line 2" | sed 'i\Test Line 1'
Test Line 1
Test Line 2
$
$ echo "Test Line 2" | sed 'a\Test Line 1'
Test Line 2
Test Line 1
$
$ echo "Test Line 2" | sed 'i\
> Test Line 1'
Test Line 1
Test Line 2
$
$ sed '3i\
> This is an inserted line.
> ' data6.txt
$ sed '$a\
> This line was added to the end of the file.
> ' data6.txt
$ sed '1i\
> This is an inserted line.\
> This is another inserted line.
> ' data6.txt
This is an inserted line.
This is another inserted line.
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
$
$ sed '2c\
> This is a changed line of text.
> ' data6.txt
This is line number 1.
This is a changed line of text.
This is the 3rd line.
This is the 4th line.
$
$ sed '/3rd line/c\
> This is a changed line of text.
> ' data6.txt
$ cat data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
$
$ sed '2,3c\
> This is a changed line of text.
> ' data6.txt
This is line number 1.
This is a changed line of text.
This is the 4th line.
$
[address]y/inchars/outchars/
$ cat data9.txt
This is line 1.
This is line 2.
This is line 3.
This is line 4.
This is line 5.
This is line 1 again.
This is line 3 again.
This is the last file line.
$
$ sed 'y/123/789/' data9.txt
This is line 7.
This is line 8.
This is line 9.
This is line 4.
This is line 5.
This is line 7 again.
This is line 9 again.
This is the last file line.
$
$ echo "Test #1 of try #1." | sed 'y/123/678/'
Test #6 of try #6.
$ echo "this is a test" | sed 'p'
this is a test
this is a test
$
$ cat data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
$
$ sed -n '/3rd line/p' data6.txt
This is the 3rd line.
$
$ sed -n '2,3p' data6.txt
This is line number 2.
This is the 3rd line.
$
$ sed -n '/3/{
> p
> s/line/test/p
> }' data6.txt
This is the 3rd line.
This is the 3rd test.
$
$ sed '=' data1.txt
1
The quick brown fox jumps over the lazy dog.
2
The quick brown fox jumps over the lazy dog.
3
The quick brown fox jumps over the lazy dog.
4
The quick brown fox jumps over the lazy dog.
$
$ cat data7.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
This is line number 1 again; we want to keep it.
This is more text we want to keep.
Last line in the file; we want to keep it.
$
$ sed -n '/text/{
> =
> p
> }' data7.txt
6
This is more text we want to keep.
$
$ cat data10.txt
This line contains tabs.
This line does contain tabs.
This line contains an escape character.
$
$ sed -n 'l' data10.txt
This\tline\tcontains\ttabs.$
This line does contain tabs.$
This line contains an escape character. \a$
$
[address]w filename
$ sed '1,2w test.txt' data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
$
$ cat test.txt
This is line number 1.
This is line number 2.
$
$ cat data12.txt
Blum, R Browncoat
McGuiness, A Alliance
Bresnahan, C Browncoat
Harken, C Alliance
$
$ sed -n '/Browncoat/w Browncoats.txt' data12.txt
$
$ cat Browncoats.txt
Blum, R Browncoat
Bresnahan, C Browncoat
$
[address]r filename
$ cat data13.txt
This is an added line.
This is a second added line.
$
$ sed '3r data13.txt' data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is an added line.
This is a second added line.
This is the 4th line.
$
$ sed '/number 2/r data13.txt' data6.txt
$ sed '$r data13.txt' data6.txt
$ cat notice.std
Would the following people:
LIST
please report to the ship's captain.
$
$ sed '/LIST/{
> r data12.txt
> d
> }' notice.std
Would the following people:
Blum, R Browncoat
McGuiness, A Alliance
Bresnahan, C Browncoat
Harken, C Alliance
please report to the ship's captain.
$
$ sed -sn '1s!/bin/sh!/bin/bash!' OldScripts/*.sh
$ sed -sn '1F;
> 1s!/bin/sh!/bin/bash!' OldScripts/*.sh