深入了解 sed 和 gawk 编辑器
在文本处理和脚本编程的世界里,
sed
和
gawk
是两款强大的工具。它们能帮助我们高效地处理和操作文本数据。下面将详细介绍它们的一些使用方法和特性。
gawk 编辑器的使用
-
从文件读取程序
:
gawk允许我们将程序存储在文件中,并在命令行中引用。例如:
$ cat script2.gawk
{print $1 "'s home directory is " $6}
$
$ gawk -F: -f script2.gawk /etc/passwd
root's home directory is /root
daemon's home directory is /usr/sbin
bin's home directory is /bin
[...]
christine's home directory is /home/christine
sshd's home directory is /run/sshd
$
在这个例子中,
script2.gawk
程序脚本使用
print
命令打印
/etc/passwd
文件中的用户名和对应的主目录。
我们还可以在程序文件中指定多个命令,只需将每个命令放在单独的一行,不需要使用分号。例如:
$ cat script3.gawk
{
text = "'s home directory is "
print $1 text $6
}
$
$ gawk -F: -f script3.gawk /etc/passwd
root's home directory is /root
daemon's home directory is /usr/sbin
bin's home directory is /bin
[...]
christine's home directory is /home/christine
sshd's home directory is /run/sshd
$
这里定义了一个变量
text
用于存储字符串,注意在
gawk
程序中引用变量值时不需要像 shell 脚本那样使用美元符号。
-
在处理数据前运行脚本
:
gawk允许我们指定程序脚本的运行时机。默认情况下,gawk从输入读取一行文本,然后对该行数据执行程序脚本。但有时我们需要在处理数据前运行脚本,比如为报告创建标题部分,这时可以使用BEGIN关键字。例如:
$ gawk 'BEGIN {print "Hello World!"}'
Hello World!
$
这里
BEGIN
关键字使
gawk
在读取数据前执行指定的脚本。如果要处理数据,还需要定义另一个脚本部分。例如:
$ 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
$
-
在处理数据后运行脚本
:与
BEGIN关键字类似,END关键字允许我们指定在读取数据后执行的程序脚本。例如:
$ 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
$
当
gawk
完成文件内容的打印后,会执行
END
脚本,这对于为报告添加页脚数据很有用。
我们可以将这些元素组合成一个完整的程序脚本文件,从简单的数据文件创建完整的报告。例如:
$ 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
$
在这个脚本中,
BEGIN
脚本创建报告的标题部分,还定义了字段分隔符
FS
;中间的脚本处理文件数据;
END
脚本生成页脚文本。
sed 编辑器的基本命令
-
更多替换选项
-
替换标志
:
sed的s命令用于替换文本,但默认只替换每行中的第一个匹配项。要处理不同位置的匹配项,需要使用替换标志。替换标志的格式为s/pattern/replacement/flags,有四种类型的替换标志:- 数字 :指定要替换的模式出现的位置。例如:
-
替换标志
:
$ cat data4.txt
This is a test of the test script.
This is the second test of the test script.
$
$ sed 's/test/trial/2' data4.txt
This is a test of the trial script.
This is the second test of the trial script.
$
- **g**:全局替换,替换文本中所有匹配的模式。例如:
$ sed 's/test/trial/g' data4.txt
This is a trial of the trial script.
This is the second trial of the trial script.
$
- **p**:打印包含匹配模式的行,通常与 `-n` 选项一起使用。例如:
$ 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.
$
- **w file**:将替换结果写入指定的文件。例如:
$ sed 's/test/trial/w test.txt' data5.txt
This is a trial line.
This is a different line.
$
$ cat test.txt
This is a trial line.
$
- **替换字符**:当文本字符串中包含难以在替换模式中使用的字符时,比如正斜杠 `/`,`sed` 允许我们选择不同的字符作为字符串分隔符。例如:
$ sed 's!/bin/bash!/bin/csh!' /etc/passwd
这里使用感叹号
!
作为分隔符,使路径名更易读。
-
使用地址
:默认情况下,
sed编辑器中的命令应用于所有文本行。如果要将命令应用于特定的行或行组,需要使用行寻址。sed有两种行寻址形式:- 数字行范围 :通过行号来引用行。例如:
$ cat data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$
$ sed '2s/dog/cat/' data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$
这里只修改了第二行的文本。还可以指定行范围,如
2,3
表示第二行到第三行,
2,$
表示从第二行到文件末尾。
-
文本模式过滤
:使用文本模式作为过滤器,只对包含指定文本模式的行应用命令。例如:
$ 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
$
这里只对包含
rich
的行应用了替换命令。
- 分组命令 :如果需要对某一行执行多个命令,可以使用花括号将命令分组。例如:
$ 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编辑器中的d命令用于删除匹配寻址方案的文本行。但要注意,如果忘记指定寻址方案,会删除所有行。例如:
$ cat data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$
$ 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
替换标志的总结表格:
| 标志 | 描述 |
| ---- | ---- |
| 数字 | 指定要替换的模式出现的位置 |
| g | 全局替换所有匹配的模式 |
| p | 打印包含匹配模式的行 |
| w file | 将替换结果写入指定的文件 |
下面是
sed
行寻址形式的流程图:
graph LR
A[行寻址] --> B[数字行范围]
A --> C[文本模式过滤]
B --> B1[单个行号]
B --> B2[行号范围]
C --> C1[固定文本模式]
C --> C2[正则表达式模式]
通过这些方法,我们可以更灵活地使用
sed
和
gawk
编辑器来处理各种文本数据。
深入了解 sed 和 gawk 编辑器
正则表达式在 sed 中的应用
在使用
sed
编辑器时,固定文本模式在过滤特定值方面有一定作用,但功能有限。
sed
支持在文本模式中使用正则表达式,这使得我们可以创建更复杂的匹配模式。
正则表达式是一种高级的文本模式匹配公式,它由一系列通配符、特殊字符和固定文本字符组合而成,几乎可以匹配任何文本情况。不过,正则表达式也是 shell 脚本编程中较难掌握的部分。
例如,若要匹配
/etc/passwd
文件中所有以数字开头的行,可以使用如下命令:
$ sed -n '/^[0-9]/p' /etc/passwd
这里的
^
表示行的开头,
[0-9]
表示匹配 0 到 9 的任意数字。
-n
选项和
p
标志一起使用,只打印匹配的行。
综合应用示例
假设我们有一个日志文件
log.txt
,内容如下:
2023-10-01 10:00:00 INFO: Operation successful
2023-10-01 10:01:00 ERROR: Something went wrong
2023-10-01 10:02:00 INFO: Another operation successful
我们想要完成以下任务:
1. 提取所有错误信息(包含
ERROR
的行)。
2. 将日期格式从
YYYY-MM-DD
转换为
MM/DD/YYYY
。
3. 为提取的错误信息添加标题和页脚。
可以使用以下
gawk
脚本完成这些任务:
$ cat log_processing.gawk
BEGIN {
print "Error Log Report"
print "----------------"
}
/ERROR/ {
split($1, date, "-");
new_date = date[2] "/" date[3] "/" date[1];
print new_date " " $2 " " $3 " " $4
}
END {
print "----------------"
print "End of Report"
}
$ gawk -f log_processing.gawk log.txt
Error Log Report
----------------
10/01/2023 10:01:00 ERROR: Something went wrong
----------------
End of Report
在这个脚本中,
BEGIN
部分打印报告的标题,中间部分处理包含
ERROR
的行,将日期格式进行转换并打印,
END
部分打印报告的页脚。
注意事项
-
数据备份
:在使用
sed和gawk处理重要文件时,务必先备份数据,以防意外修改导致数据丢失。 - 正则表达式复杂度 :正则表达式虽然强大,但过于复杂的表达式可能会降低脚本的可读性和性能,应尽量保持简洁。
- 脚本测试 :在将脚本应用于实际数据之前,先在小样本数据上进行测试,确保脚本按预期工作。
下面是处理日志文件的操作步骤列表:
1. 创建
log_processing.gawk
脚本文件。
2. 编写脚本内容,包括
BEGIN
、中间处理和
END
部分。
3. 运行
gawk -f log_processing.gawk log.txt
命令处理日志文件。
4. 检查输出结果,确保符合预期。
下面是
gawk
脚本处理日志文件的流程图:
graph LR
A[开始] --> B[执行 BEGIN 脚本]
B --> C[读取日志文件行]
C --> D{是否包含 ERROR}
D -- 是 --> E[处理日期格式并打印]
D -- 否 --> C
C --> F{是否到达文件末尾}
F -- 否 --> C
F -- 是 --> G[执行 END 脚本]
G --> H[结束]
通过深入学习和实践,我们可以熟练掌握
sed
和
gawk
编辑器的使用,利用它们的强大功能处理各种复杂的文本处理任务。无论是日常的日志分析,还是数据文件的格式转换,
sed
和
gawk
都能成为我们高效处理数据的得力工具。
超级会员免费看
65

被折叠的 条评论
为什么被折叠?



