Linux 中最常用的文本处理编辑器 —— 初识 sed 和 gawk
发布日期:2021-06-30 15:03:01 浏览次数:2 分类:技术文章

本文共 5305 字,大约阅读时间需要 17 分钟。

contents

== 0. 待修改 ==

shell 脚本最常见的一个用途就是处理文本文件。检查日志文件、读取配置文件、处理数据元素,shell 脚本可以帮助我们将文本中各种数据的日常处理任务自动化。

sedgawk 工具能够简化数据处理任务。

1. 文本处理

1.1 sed 编辑器

与普通交互式文本编辑器恰好相反,它是一种轻量级流编辑器。

  • 交互式文本编辑器中,你可以使用键盘来插入、删除、替换数据。
  • 流编辑器中,在编辑数据前会基于预先提供的规则来编辑数据流。

sed 编辑器可以根据命令来处理数据流中的数据,那些命令要么从命令行中输入,要么存储在一个命令文本文件中。要注意的是,它不仅能够修改文件内容,还能修改命令的结果。

sed 编辑器会执行如下操作:

  1. 一次从输入中读取一行数据。
  2. 根据所提供的编辑器命令匹配数据。
  3. 按照命令修改流中的数据。
  4. 将新的数据输出到 STDOUT

它会将文件中的每一行数据都进行处理,遍历完毕所有的数据行后,它就会终止。

sed 编辑器只需要对数据流进行一遍处理就可以完成编辑操作,效率比交互式编辑器高,可以快速完成对数据的自动修改。

sed options script file
options descriptions
-n 一般sed命令会把所有数据都输出到屏幕,如果加入此选项,则只会把经过sed命令处理的行输出到屏幕
-e script 允许对输入数据应用多条sed命令编辑,将script中指定的命令添加到已有的命令中
-f file 允许对输入数据应用多条sed命令编辑, 将file中指定的命令添加到已有的命令中
-i 用sed修改结果直接修改读取数据的文件,而不是由屏幕输出

除了 -i 选项,命令只针对屏幕输出进行修改操作。

script descriptiongs
a \ 追加,在当前行后添加一行或多行,添加多行时,除最后一行外,每行末尾需要用 \ 代表数据未完结
c \ 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾用 \ 代表数据未完结
i \ 插入,在当前行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用 \ 代表数据未完结
d 删除指定行
p 输出指定行
s 字符替换,用一个字符串替换另外一个字符串

1.1.1 在命令行定义编辑器命令

默认情况下,sed 编辑器会将指定的命令应用到 STDIN 输入流上,这样你可以直接将数据通过管道输入 sed 编辑器处理。

$ echo "This is a test." | sed 's/test/big test/' # 斜线间指定的第二个文本字符串来替换第一个文本字符串模式This is a big test.
sed 's/test/big test' data.txt

针对文件的每行内容进行处理。

1.1.2 在命令行使用多个编辑器命令

使用 -e 选项。

sed -e 's/brown/green/; s/dog/cat/' data.txt # 命令之间用分号隔开,命令末尾和分号之间不能有空格。

或者也可以采用下面的形式:

sed -e ' # 次提示符起始,输入每行命令s/brown/green/s/fox/elephant/s/dog/cat/' data.txt # 次提示符结束

将指定的每条命令应用到文本文件中的每一行上。

1.1.3 从文件中读取编辑器命令

使用 -f 参数来指定命令文件,不用在每条命令后面放一个分号,sed 编辑器知道每行都是一条单独的命令,sed 编辑器会从指定文件中读取命令,并将它们应用到数据文件中的每一行上。

# script.seds/brown/green/s/fox/elephant/s/dog/cat/
sed -f script.sed data.txt

1.2 gawk 程序

一种编程语言。

  • 定义变量来保存数据
  • 使用算数和字符操作符来处理数据
  • 使用结构化编程概念来为数据处理增加逻辑
  • 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告

生成格式化日志文件,gawk 程序可以让你从日志文件中过滤出需要的数据元素,然后你可以将其格式化,使得重要的数据更易于阅读。

1.2.1 gawk 命令格式

gawk options program file
options descriptions
-F fs 指定行中划分数据字段的字段分隔符
-f file 从指定的文件中读取程序
-v variable 定义 gawk 程序中的一个变量及其默认值
-mf N 指定要处理的数据文件中的最大子段数量
-mr N 指定数据文件中的最大数据行数
-W keyword 指定gawk的兼容模式或警告等级

gawk 的强大之处在于它可以写脚本来读取文本行的数据,然后处理并显示数据。

1.2.2 从命令行读取程序脚本

gawk 程序脚本用一对花括号来定义,命令行假定脚本是个单个文本字符串,你需要将脚本放到单引号中。如果没有在命令行上指定文件名,gawk 程序会从 STDIN 接受数据,意味着你还需要手动输入字符串供其处理。

Ctrl +D组合键产生一个 EOF 字符,能够终止字符串的输入。

1.2.3 使用数据字段变量

  • $0 代表整个文本行
  • $1 代表文本行中的第1个数据字段
  • $2 代表文本行中的第2个数据字段
  • $n 代表文本行中的第n个数据字段

在文本行中,每个数据字段都是通过字段分隔符划分的。gawk 在读取一行文本时,会用预定义的字段分隔符划分每个数据字段。gawk 中默认的字段分隔符时任意的空白字符(例如空格或制表符)。

#data.txtOne line of test text.Two lines of test text.Three lines of test text.

只显示第一个字段的值。

$ gawk '{print $1}' data.txtOneTwoThree

读取使用 : 分隔符的文件。

gawk -F: '{print $1}' /etc/passwd

1.2.4 在程序脚本中使用多个命令

gawk 编程语言允许你将多条命令组合成一个正常的程序。

$ echo 'My name is Rich' | gawk '{
$4="Christine"; print $0}'My name is Christine
gawk '{$4="Christine"print $0}'My name is RichMy name is Christine

要想退出程序,Ctrl+D。

1.2.5 从文件中读取程序

# script.gawk{
print $1 "'s home directory is " $6}
gawk -F: -f script.gawk /etc/passwd
# script.gawk{
text = "'s home directory is "print $1 text $6}

gawk 中引用变量并不需要使用美元符。

1.2.6 在处理数据前运行脚本

BEGIN 关键字可以强制 gawk 在读取数据前执行 BEGIN 关键字后指定的程序脚本。

gawk 'BEGIN {print "Hello World!"}'
gawk 'BEGIN {print "The data File Contents"}{print $0}' data.txt

1.2.7 在处理数据后运行脚本

gawk 'BEGIN {print "The data File Contents"}{print $0}END {print "End of File"}' data.txt

从数据文件中生成报告脚本:

# script.gawkBEGIN {
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"}

2. sed 编辑器基础

2.1 更多的替换选项

2.1.1 替换标记

默认替换只会替换每行出现的第一个文本。

s/pattern/replacement/flags

  • 数字,表明新文本将替换第几处模式匹配的地方。
  • g,表明新文本将会替换所有匹配的文本。
  • p,表明原先行的内容要打印出来。
  • w file,将替换的结果写到文件中。

2.1.2 替换字符

用 C shell 替换 bash shell。

sed 's!/bin/bash!/bin/csh!' /etc/passwd

感叹号被用作字符串分隔符。

2.2 使用地址

默认情况下,sed 命令会作用于全部行,如果想指定特定行,需要使用行寻址。

  • 以数字形式表示行区间
  • 用文本模式来过滤出行

2.2.1 以数字方式的行寻址

sed '2s/dog/cat/' data.txt

只修改第二行文本。

sed '2,3s/dog/cat/' data.txt

指定行区间。

sed '2,$s/dog/cat/' data.txt

从第二行开始的所有行。

2.2.2 使用文本过滤器

pattern/command

还是使用正则表达式好一些。

2.2.3 命令组合

sed '2{s/fox/elephant/s/dog/cat/}' data.txt

两条命令都会作用在该地址上。

sed '3,${s/fox/elephant/s/dog/cat/}' data.txt

2.3 删除行

sed 'd' data.txt

删除所有行。

sed '3d' data.txt

删除第 3 行。

sed '2,3d' data.txt

指定行区间。

sed 编辑器不会修改原始文件,除非你写入原文件。

2.4 插入和附加文本

  • 插入(i):会在指定行前增加一个新行
  • 附加(a):会在指定行后增加一个新行
sed '[address]command\newline'
echo "Test Line 2" | sed "i\Test Line 1"Test Line 1Test Line 2

将一个新行插入到数据流第 3 行前。

sed '3i\This is an inserted line.' data.txt

$ 符号同样适用。

2.5 修改行

sed '3c\This is an inserted line.' data.txt

文本模式修改:

sed '/number 3/c\This is an inserted line.' data.txt

使用地址区间?

sed '2,3c\This is an inserted line.' data.txt

sed 编辑器会用一行文本来替换数据流中的两行文本。

2.6 转换命令

[address]y/inchars/outchars/

转换命令会对 inchars 和 outchars 值进行一对一的映射。inchars 中的第一个字符会被转换为 outchars 中的第一个字符,第二个字符会被转换成 outchars 中的第二个字符。如果 inchars 和 outchars 的长度不同,那么 sed 编辑器会产生一条错误消息。

可以处理单个字符。

sed 'y/123/789/' data.txt

用7来替换1,用8来替换2,用9来替换3。

全局命令。

2.7 回顾打印

  • p 命名用来打印文本行
  • 等号命令用来打印行号
  • l 用来列出行

2.7.1 打印行

echo "this is a test" | sed 'p'

打印包含有匹配文本模式的行:

sed -n '/number 3/p' data.txt

-n 选项可以禁止输出其他行。

sed -n '2,3p' data.txt

2.7.2 打印行号

sed '=' data.txt
sed -n '/number 4/{=p}' data.txt

2.7.3 列出行

命令(l)能够打印数据流中的文本和不可打印的ASCII字符。

sed 'l' data.txt

2.8 使用 sed 处理文件

2.8.1 写入文件

[address]w filename

w 命令用来向文件写入行。

sed '1,2w test.txt' data.txt

将数据流(data.txt)中的前两行打印到一个文本文件(text.txt)中。

2.8.2 从文件读取数据

将一个独立文件中的数据插入到数据流中。

[address]r filename
sed '3r data.txt' data.txt

转载地址:https://jiaming.blog.csdn.net/article/details/104942978 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:正则表达式
下一篇:第六章:内置模块(Ⅱ)

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年05月01日 06时06分47秒