sed与gawk快速指南
在shell脚本中进行数据处理时,常常需要用到
sed
或
gawk
程序(有时两者都要用到)。本文将为你提供
sed
和
gawk
命令的快速参考,让你在处理数据时更加得心应手。
1. sed编辑器
sed
编辑器可以根据你在命令行输入或存储在命令文本文件中的命令来处理数据流中的数据。它逐行读取输入数据,将数据与提供的编辑器命令进行匹配,按照命令中的指定修改数据流中的数据,然后将新数据输出到标准输出。
1.1 启动sed编辑器
使用
sed
命令的格式如下:
sed options script file
选项参数可以自定义
sed
命令的行为,具体选项如下表所示:
| 选项 | 描述 |
| ---- | ---- |
| -e script | 将
script
中指定的命令添加到处理输入时运行的命令中 |
| -f file | 将
file
文件中指定的命令添加到处理输入时运行的命令中 |
| -n | 不为每个命令产生输出,而是等待打印命令 |
script
参数指定要应用于流数据的单个命令。如果需要多个命令,则必须使用
-e
选项在命令行中指定,或者使用
-f
选项在单独的文件中指定。
1.2 sed命令
sed
编辑器脚本包含针对输入流中每一行数据进行处理的命令。以下是一些常用的
sed
命令:
1.2.1 替换命令(s)
s
命令用于替换输入流中的文本,格式如下:
s/pattern/replacement/flags
-
pattern:要替换的文本。 -
replacement:sed插入的新文本。 -
flags:控制替换的方式,有以下四种类型: - 数字:指定要替换的模式出现的位置。
-
g:替换所有出现的文本。 -
p:打印原始行的内容。 -
w file:将替换结果写入文件。
例如,要替换第二个匹配模式的出现位置,可以使用数字
2
:
$ sed 's/pattern/replacement/2' data
1.2.2 地址指定
默认情况下,
sed
编辑器中的命令应用于文本数据的所有行。如果要将命令应用于特定的行或一组行,则必须使用行寻址。
sed
编辑器中有两种行寻址形式:
- 数字行范围
- 过滤行的文本模式
两种形式指定地址的格式相同:
[address]command
使用数字行寻址时,通过文本流中的行位置引用行。
sed
编辑器将文本流中的第一行分配为行号
1
,并为每一行依次编号。例如,要将数据文件中第2行或第3行的
dog
替换为
cat
,可以使用以下命令:
$ sed '2,3s/dog/cat/' data1
另一种限制命令应用行的方法是指定文本模式,格式如下:
/pattern/command
必须用正斜杠将指定的模式括起来。
sed
编辑器仅将命令应用于包含指定文本模式的行。例如:
$ sed '/rich/s/bash/csh/' /etc/passwd
此命令会找到包含
rich
的行,并将
bash
替换为
csh
。
你还可以为特定地址组合多个命令:
address {
command1
command2
command3
}
sed
编辑器仅将指定的每个命令应用于与指定地址匹配的行。例如:
$ sed '2{
> s/fox/elephant/
> s/dog/cat/
> }' data1
此命令将每个替换应用于数据文件的第二行。
1.2.3 删除行(d)
d
命令用于删除与提供的寻址方案匹配的任何文本行。使用时要小心,如果忘记包含寻址方案,将删除流中的所有行:
$ sed 'd' data1
d
命令与指定地址结合使用时最为有用,可以按行号或特定行范围删除数据流中的特定文本行:
$ sed '3d' data1
$ sed '2,3d' data1
sed
编辑器的模式匹配功能也适用于删除命令:
$ sed '/number 1/d' data1
此命令仅删除流中与指定文本匹配的行。
1.2.4 插入和追加文本
sed
编辑器允许你在数据流中插入和追加文本行。插入命令(
i
)在指定行之前添加新行,追加命令(
a
)在指定行之后添加新行。这两个命令的格式可能会让人困惑,不能在单个命令行中使用,必须在单独的行上指定要插入或追加的行,格式如下:
sed '[address]command\
new line'
例如:
$ echo "testing" | sed 'i\
> This is a test'
This is a test
testing
$
$ echo "testing" | sed 'a\
> This is a test'
testing
This is a test
$
1.2.5 更改行(c)
c
命令用于更改数据流中整行文本的内容,使用方法与插入和追加命令类似,必须在单独的行上指定新行:
$ sed '3c\
> This is a changed line of text.' data1
1.2.6 转换命令(y)
y
命令是
sed
编辑器中唯一对单个字符进行操作的命令,格式如下:
[address]y/inchars/outchars/
该命令对
inchars
和
outchars
的值进行一对一映射。例如:
$ sed 'y/abc/ABC/' data
此命令将输入流中的
a
、
b
、
c
分别转换为
A
、
B
、
C
。
1.2.7 打印行(p)
p
命令类似于替换命令中的
p
标志,用于打印
sed
编辑器输出中的行。最常见的用途是打印包含与文本模式匹配的文本的行:
$ sed -n '/number 3/p' data1
This is line number 3.
$
1.2.8 写入文件(w)
w
命令用于将行写入文件,格式如下:
[address]w filename
filename
可以是相对或绝对路径名,但运行
sed
编辑器的人必须对该文件具有写入权限。
address
可以是
sed
中使用的任何类型的寻址方法。例如:
$ sed '1,2w test' data1
此命令将数据流的前两行打印到文本文件
test
中。
1.2.9 从文件读取(r)
r
命令允许你插入单独文件中包含的数据,格式如下:
[address]r filename
filename
参数指定包含数据的文件的绝对或相对路径名。不能对
r
命令使用地址范围,只能指定单个行号或文本模式地址。
sed
编辑器在地址之后插入文件中的文本。例如:
$ sed '3r data' data1
此命令将
data
文件的完整文本插入到
data1
文件中,从
data1
文件的第3行开始。
下面是
sed
编辑器操作的流程图:
graph TD;
A[开始] --> B[读取输入数据];
B --> C[匹配命令];
C --> D{是否有匹配};
D -- 是 --> E[执行命令];
D -- 否 --> F[跳过];
E --> G[输出结果];
F --> G;
G --> H{是否还有数据};
H -- 是 --> B;
H -- 否 --> I[结束];
2. gawk程序
gawk
程序是Unix中原始
awk
程序的GNU版本。
awk
程序通过提供一种编程语言,而不仅仅是编辑器命令,将流编辑提升到了一个新的水平。
2.1 gawk命令格式
gawk
程序的基本格式如下:
gawk options program file
gawk
程序的选项如下表所示:
| 选项 | 描述 |
| ---- | ---- |
| -F fs | 指定用于划分行中数据字段的文件分隔符 |
| -f file | 指定要从中读取程序的文件名 |
| -v var=value | 定义
gawk
程序中使用的变量和默认值 |
| -mf N | 指定要处理的数据文件中的最大字段数 |
| -mr N | 指定数据文件中的最大记录大小 |
| -W keyword | 指定
gawk
的兼容模式或警告级别,使用
help
选项列出所有可用的关键字 |
2.2 使用gawk
你可以直接从命令行或在shell脚本中使用
gawk
。以下是使用
gawk
的方法:
2.2.1 从命令行读取程序脚本
gawk
程序脚本由左右花括号定义,必须将脚本命令放在两个花括号之间。由于
gawk
命令行假设脚本是一个文本字符串,因此还必须将脚本用单引号括起来。例如:
$ gawk '{print $1}'
此脚本显示输入流中每行的第一个数据字段。
2.2.2 在程序脚本中使用多个命令
gawk
编程语言允许你将多个命令组合成一个正常的程序。在命令行指定的程序脚本中使用多个命令时,只需在命令之间放置分号:
$ echo "My name is Rich" | gawk '{$4="Dave"; print $0}'
My name is Dave
$
此脚本执行两个命令:将第四个数据字段替换为不同的值,然后显示流中的整个数据行。
2.2.3 从文件读取程序
与
sed
编辑器一样,
gawk
编辑器允许你将程序存储在文件中,并在命令行中引用它们:
$ cat script1
{ print $5 "'s userid is " $1 }
$ gawk -F: -f script1 /etc/passwd
gawk
程序对输入流数据执行文件中指定的所有命令。
2.2.4 在处理数据之前运行脚本
gawk
程序允许你指定程序脚本的运行时间。默认情况下,
gawk
从输入中读取一行文本,然后对该行文本中的数据执行程序脚本。有时,你可能需要在处理数据之前运行脚本,例如为报告创建标题部分。可以使用
BEGIN
关键字来实现:
$ gawk 'BEGIN {print "This is a test report"}'
This is a test report
$
你可以在
BEGIN
部分放置任何类型的
gawk
命令,例如为变量分配默认值的命令。
2.2.5 在处理数据之后运行脚本
与
BEGIN
关键字类似,
END
关键字允许你指定
gawk
在读取数据后执行的程序脚本:
$ gawk 'BEGIN {print "Hello World!"} {print $0} END {print "byebye"}' data1
Hello World!
This is a test
This is a test
This is another test.
This is another test.
byebye
$
gawk
程序首先执行
BEGIN
部分的代码,然后处理输入流中的任何数据,最后执行
END
部分的代码。
2.3 gawk变量
gawk
程序不仅仅是一个编辑器,它还是一个完整的编程环境。以下是一些重要的
gawk
变量:
2.3.1 内置变量
gawk
程序使用内置变量来引用程序数据中的特定功能,以下是一些常用的内置变量:
| 变量 | 描述 |
| ---- | ---- |
| $0 | 整个数据记录 |
| $1 | 记录中的第一个数据字段 |
| $2 | 记录中的第二个数据字段 |
| $n | 记录中的第
n
个数据字段 |
| FIELDWIDTHS | 以空格分隔的数字列表,定义每个数据字段的精确宽度 |
| FS | 输入字段分隔符字符 |
| RS | 输入记录分隔符字符 |
| OFS | 输出字段分隔符字符 |
| ORS | 输出记录分隔符字符 |
除了字段和记录分隔符变量外,
gawk
还提供了其他一些内置变量,帮助你了解数据的情况并从shell环境中提取信息,如下表所示:
| 变量 | 描述 |
| ---- | ---- |
| ARGC | 命令行参数的数量 |
| ARGIND | 当前正在处理的文件在
ARGV
中的索引 |
| ARGV | 命令行参数的数组 |
| CONVFMT | 数字的转换格式,默认值为
%.6g
|
| ENVIRON | 当前shell环境变量及其值的关联数组 |
| ERRNO | 读取或关闭输入文件时发生错误的系统错误 |
| FILENAME | 用于输入到
gawk
程序的数据文件的文件名 |
| FNR | 数据文件中的当前记录号 |
| IGNORECASE | 如果设置为非零值,
gawk
在所有字符串函数(包括正则表达式)中忽略所有字符的大小写 |
| NF | 数据文件中的数据字段总数 |
| NR | 处理的输入记录数 |
| OFMT | 显示数字的输出格式,默认值为
%.6g
|
| RLENGTH | 匹配函数中匹配的子字符串的长度 |
| RSTART | 匹配函数中匹配的子字符串的起始索引 |
2.3.2 在脚本中分配变量
在
gawk
程序中为变量分配值与在shell脚本中类似,使用赋值语句:
$ gawk '
> BEGIN{
> testing="This is a test"
> print testing
> }'
This is a test
$
分配值后,你可以在
gawk
脚本的任何位置使用该变量。
2.3.3 在命令行分配变量
你还可以使用
gawk
命令行为
gawk
程序的变量分配值,这样可以在正常代码之外设置值,动态更改值。例如:
$ cat script1
BEGIN{FS=","}
{print $n}
$ gawk -f script1 n=2 data1
$ gawk -f script1 n=3 data1
2.4 gawk程序特性
gawk
程序的一些特性使其在处理数据时非常方便,能够创建可以解析几乎任何类型文本文件(包括日志文件)的
gawk
脚本。
2.4.1 正则表达式
你可以使用基本正则表达式(BRE)或扩展正则表达式(ERE)来过滤程序脚本应用的数据流中的行。使用正则表达式时,正则表达式必须出现在它控制的程序脚本的左花括号之前:
$ gawk 'BEGIN{FS=","} /test/{print $1}' data1
This is a test
$
2.4.2 匹配运算符
匹配运算符(
~
)允许你将正则表达式限制在记录中的特定数据字段。例如:
$1 ~ /^data/
此表达式过滤第一个数据字段以
data
开头的记录。
2.4.3 数学表达式
除了正则表达式,你还可以在匹配模式中使用数学表达式,这在匹配数据字段中的数值时非常有用。例如,要显示所有属于根用户组(组号为
0
)的系统用户,可以使用以下脚本:
$ gawk -F: '$4 == 0{print $1}' /etc/passwd
2.4.4 结构化命令
gawk
程序支持以下结构化命令:
-
if-then-else
语句:
if (condition) statement1; else statement2
-
while语句:
while (condition) {
statements
}
-
do-while语句:
do {
statements
} while (condition)
-
for语句:
for(variable assignment; condition; iteration process)
这些结构化命令为
gawk
脚本程序员提供了丰富的编程机会,你可以编写与几乎任何高级语言程序功能相媲美的
gawk
程序。
下面是
gawk
程序处理数据的流程图:
graph TD;
A[开始] --> B[读取数据];
B --> C{是否有BEGIN部分};
C -- 是 --> D[执行BEGIN部分代码];
C -- 否 --> E[跳过BEGIN部分];
D --> E;
E --> F{是否还有数据};
F -- 是 --> G[执行程序脚本];
F -- 否 --> H{是否有END部分};
G --> F;
H -- 是 --> I[执行END部分代码];
H -- 否 --> J[结束];
I --> J;
通过本文的介绍,你应该对
sed
和
gawk
有了更深入的了解。它们是强大的数据处理工具,能够帮助你高效地处理各种文本数据。希望这些知识能在你的日常工作中发挥作用。
3. 总结与应用示例
3.1 总结
sed
和
gawk
都是强大的数据处理工具,在shell脚本中有着广泛的应用。
sed
主要用于对数据流进行简单的文本替换、插入、删除等操作,通过灵活的地址指定,可以精确地处理特定的行。而
gawk
则提供了更高级的功能,它是一种编程语言,支持正则表达式、数学表达式、结构化命令等,能够处理更复杂的数据处理任务,如解析日志文件、统计数据等。
下面是
sed
和
gawk
的主要特点对比:
| 工具 | 特点 |
| ---- | ---- |
|
sed
| 操作简单,适用于简单的文本处理,如替换、插入、删除等;支持行寻址,可精确处理特定行 |
|
gawk
| 功能强大,提供编程语言,支持正则表达式、数学表达式、结构化命令;可处理复杂的数据处理任务,如解析日志文件、统计数据等 |
3.2 应用示例
3.2.1 使用
sed
清理日志文件
假设我们有一个日志文件
log.txt
,其中包含一些无用的信息,我们想要删除这些信息。例如,日志文件中包含
[DEBUG]
级别的日志信息,我们想要删除这些信息。可以使用以下
sed
命令:
$ sed '/\[DEBUG\]/d' log.txt > clean_log.txt
这个命令会删除
log.txt
中所有包含
[DEBUG]
的行,并将结果保存到
clean_log.txt
文件中。
3.2.2 使用
gawk
统计日志文件中的错误数量
假设我们有一个日志文件
log.txt
,其中包含
[ERROR]
级别的日志信息,我们想要统计这些错误的数量。可以使用以下
gawk
命令:
$ gawk '/\[ERROR\]/{count++} END {print "Error count: " count}' log.txt
这个命令会统计
log.txt
中所有包含
[ERROR]
的行的数量,并在处理完所有数据后输出错误数量。
3.2.3 使用
sed
和
gawk
结合处理数据
假设我们有一个数据文件
data.txt
,其中包含用户的姓名和年龄,格式如下:
John,25
Jane,30
Bob,35
我们想要将年龄大于30的用户的姓名提取出来,并将姓名转换为大写。可以使用以下命令:
$ gawk -F ',' '$2 > 30 {print $1}' data.txt | sed 's/.*/\U&/'
这个命令首先使用
gawk
过滤出年龄大于30的用户的姓名,然后使用
sed
将姓名转换为大写。
3.3 操作步骤总结
以下是使用
sed
和
gawk
进行数据处理的一般操作步骤:
1.
确定需求
:明确需要处理的数据和要实现的功能。
2.
选择工具
:根据需求选择合适的工具,
sed
适用于简单的文本处理,
gawk
适用于复杂的数据处理。
3.
编写命令
:根据工具的语法编写相应的命令。
4.
测试命令
:在小数据集上测试命令,确保命令能够正常工作。
5.
应用命令
:在实际数据集上应用命令,处理数据。
3.4 操作流程图
graph TD;
A[确定需求] --> B[选择工具];
B --> C[编写命令];
C --> D[测试命令];
D -- 成功 --> E[应用命令];
D -- 失败 --> C;
通过以上的介绍和示例,你可以更好地掌握
sed
和
gawk
的使用方法,在实际工作中灵活运用这两个工具,提高数据处理的效率。
超级会员免费看
36

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



