禅道博客

分享专业技术知识,文章内容干货满满

《Linux命令行与shell脚本编程大全》第十九章:初识sed和gawk

2022-11-29 10:24:23
刘沙沙
原创 166
摘要:本文详细介绍了《Linux命令行与shell脚本编程大全》关于sed和gawk部分的知识。

19.1 文本处理

19.1.1 sed编辑器

sed编辑器处理数据流的命令有两种输入方式:从命令行输入,或者存储在一个命令文本文件中。


  • sed命令格式:sed options script file,选项允许修改sed命令的行为。
  • sed命令选项:


-e script

在处理输入时,将script中指定的命令添加到已有的命令中

-f file 

在处理输入时,将file中指定的命令添加到已有的命令中

-n

不产生命令输出,使用print命令来完成输出

如果需要用多个命令,要么使用-e选项在命令行中指定,要么使用-f选项在单独的文件中指定。


1. 在命令行定义编辑器命令

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

file-download-567586.json

s命令会用斜线间指定的第二个文本字符串来替换第 一个文本字符串模式,除了修改单行数据,sed编辑器也可以处理整个文件中的多行数据。

file-download-567587.json

sed编辑器并不会修改文本文件的数据。它只会将修改后的数据发送到 STDOUT。


2. 在命令行使用多个编辑器命令

在sed命令行上执行多个命令时,只要用-e选项就可以了,多个命令间加分号且命令之间没有空格。

file-download-567588.json

如果不用分号,也可以用bash shell的次提示符来分隔命令。需要输入第一个单引号标识出sed程序脚本的起始,bash会提示你输入更多命令,直到输入了标示结束的单引号。

file-download-567589.json

注意:要在封尾单引号所在行结束命令。bash shell一旦发现了封尾的单引号,就会执行命令。


3. 从文件中读取编辑器命令

如果有大量要处理的sed命令,可以将它们放进一个单独的文件中,在sed命令中用-f选项来指定文件。只需要将每条命令单独放一行,无需加分号。

file-download-567590.json

19.1.2 gawk程序

gawk能提供一个类编程环境来修改和重新组织文件中的数据,gawk程序提供了一种编程语言而不只是编辑器命令。在gawk编程语言中,我们可以:

  • 定义变量来保存数据;
  • 使用结构化编程概念(比如if-then语句和循环)来为数据处理增加处理逻辑;
  • 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告。


1. gawk命令格式

gawk options program file

gawk选项

-F fs

指定行中划分数据字段的字段分隔符

-f file

从指定的文件中读取程序

-v var=value

定义gawk程序中的一个变量及其默认值

-mf N

指定要处理的数据文件中的最大字段数

-mr N

指定数据文件中的最大数据行数

-W keyword

指定gawk的兼容模式或警告等级


2. 从命令行读取程序脚本

gawk程序脚本用一对花括号定义。需要将脚本命令放到两个{ }中。

file-download-567591.json

还需要将脚本放到单引号中。如下:

gawk '{print "Hello World!"}'

直接执行这个命令不会输出任何内容,因为在运行这个程序时,它会一直等待从STDIN输入的文本。所以需要在数据流中输入文本。

file-download-567592.json

输入Ctrl+D组合键终止gawk程序。


3. 使用数据字段变量

gawk会自动给一行中的每个数据元素分配一个变量,gawk会将如下变量分配给它在文本行中发现的数据字段。

$0代表整个文本行;

$1代表文本行中的第1个数据字段;

$2代表文本行中的第2个数据字段;

$n代表文本行中的第n个数据字段。

gawk中默认的字段分隔符是任意的空白字符,下图会显示test1.sh文件中每行第一个数据字段的值。

file-download-567593.json

如果要采用其他的字段分隔符文件,可以用-F选项指定。

file-download-567594.json


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

要在命令行上的程序脚本中使用多条命令,只要在命令之间放个分号即可。

file-download-567595.json

也可以用次提示符一次一行地输入程序脚本命令,同sed。

file-download-567596.json


5. 从文件中读取程序

单条命令用{ }括起来即可。

file-download-567597.json

多条命令,一条命令放一行,用{ }括起来,不需要用分号。

file-download-567598.json

注意:gawk 程序在引用变量值时无需使用$符号。


6. 在处理数据前运行脚本

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

file-download-567599.json


7. 在处理数据后运行脚本

END关键字gawk会在读完数据后执行其后的程序脚本。

file-download-567600.json

当gawk程序打印完文件内容后,它会执行END脚本中的命令。这是在处理完所有正常数据后给报告添加页脚的最佳方法。

file-download-567602.json

19.2 sed编辑器基础

19.2.1 更多的替换选项

1.替换标记

file-download-567604.json

替换命令在替换多行中的文本时默认情况下它只替换每行中出现的第一处,要让替换命令能够替换一行中不同地方出现的文本必须使用替换标记。

格式为:s/pattern/replacement/flags,有4种可用的替换标记:

数字

表明新文本将替换第几处模式匹配的地方

g

表明新文本将会替换所有匹配的文本

p

表明原先行的内容要打印出来

w file

将替换的结果写到文件中

file-download-567605.json

file-download-567606.json


  • p替换标记会打印与替换命令中指定的模式匹配的行,通常和sed的-n选项一起使用;
  • -n选项将禁止sed编辑器输出。但p替换标记会输出修改过的行;
  • 将二者配合使用的效果就是只输出被替换命令修改过的行。


file-download-567607.json

w替换标记可以将匹配的行输出保存到指定文件中。

file-download-567608.json


2. 替换字符

感叹号“!”被用作字符串分隔符,比如用C shell替换/etc/passwd文件中的bash shell。

file-download-567609.json

19.2.2 使用地址

默认情况下,sed编辑器中使用的命令会作用于文本数据的所有行。如果只想将命令作用于特定行或某些行,则必须用行寻址。在sed编辑器中有两种形式的行寻址: 

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


1. 数字方式的行寻址

格式[address]command指定的地址可以是单个行号,或是用起始行号、逗号以及结尾行号指定的一定 区间范围内的行。

  • 单个行号;
  • 行地址区间。

file-download-567610.json

如果想将命令作用到文本中从某行开始的所有行,可以用特殊地址——美元符

file-download-567611.json


2. 使用文本模式过滤器

格式:/pattern/command,必须用正斜线将要指定的pattern封起来。sed编辑器会将该命令作用到包含指定文本模式的行上。

file-download-567612.json

file-download-567613.json

file-download-567614.json


3. 命令组合

如果需要在单行上执行多条命令,可以用花括号将多条命令组合在一起。

file-download-567615.json

file-download-567616.json

19.2.3 删除行

删除命令d会删除匹配指定寻址模式的所有行。使用该命令时要加入寻址模式,否则流中的所有文本行都会被删除。


  • “d”删除所有行;
  • “3d”删除第三行;
  • “1,3d”删除1到3行;
  • “2,$d”删除第2行后所有的行。


file-download-567617.json

sed编辑器的模式匹配特性也适用于删除命令,会删掉包含匹配指定模式的行。

file-download-567618.json

使用两个文本模式来删除某个区间内的行,但是第一个模式会“打开”行删除功能,第二个模式会“关闭”行删除功能。sed编辑器会删除两个指定行之间的所有行(包括指定的行)。

file-download-567619.json

上图中第二个出现数字“1”的行再次触发了删除命令,因为没有找到停止模式,所以就将数据流中的剩余行全部删除了。另外如果指定了一个从未在文本中出现的停止模式,一直匹配不到结束模式,整个数据流都会被删掉。

file-download-567620.json

19.2.4 插入和附加文本

sed编辑器允许向数据流插入和附加文本行:


  • 插入(insert)命令(i)会在指定行前增加一个新行;
  • 附加(append)命令(a)会在指定行后增加一个新行。


不能在单个命令行上使用,你必须指定是要将 行插入还是附加到另一行。格式如下:

sed '[address]command\new line'

i命令插入到数据流文本前面,a命令插入到数据流文本后面。

file-download-567621.json

同样可以配合寻址,将文本插入或附加到单个行的前面或后面。

file-download-567622.json

使用$符号可以将新行附加到数据流的末尾。

file-download-567623.json

要插入或附加多行文本,需要对插入或附加的新文本中的每一行使用反斜线。

file-download-567624.json

19.2.5 修改行

修改(change)命令允许修改数据流中整行文本的内容。必须在sed命令中单独指定新行。

file-download-567625.json

也可以用文本模式来寻址来修改。

file-download-567626.json

注意,修改命令使用区间寻址时,会用这一行文本来替换区间文本,而不是逐一修改这两行文本。

file-download-567627.json

19.2.6 转换命令

转换(transform)命令(y)是唯一可以处理单个字符的sed编辑器命令,转换命令格式如下:

[address]y/inchars/outchars/

比如sed 'y/123/789/' test1.sh,test.sh中的1会被转换成7,2转换成8,3转换成9。转换命令是一个全局命令,会找到所有指定字符自动进行转换,跟位置无关。

file-download-567628.json

19.2.7 回顾打印

1. 打印行


  • p命令打印所有的的行;
  • 使用-n禁止输出其他行,只打印包含匹配文本模式的行。


file-download-567629.json

要在替换之前查看,也可使用打印命令。


2. 打印行号

等号命令会打印行在数据流中的当前行号。

file-download-567631.json

要在数据流中查找特定文本模式,利用-n选项,可以只显示包含匹配文本模式的行的行号和文本。


3. 列出行

列出(list)命令(l)可以打印数据流中的文本和不可打印的ASCII字符。比如文本中包含制表符,可以通过l命令打印出来。

file-download-567633.json

19.2.8 使用sed处理文件

1. 写入文件

w命令用来向文件写入行,格式为: [address]w filename,filename可以使用相对路径或绝对路径但是必须有文件的写权限。

file-download-567634.json


2. 从文件读取数据

读取(read)命令(r)允许将一个独立文件中的数据插入到数据流中。读取命令的格式: [address]r filename

file-download-567635.json

发表评论
评论通过审核后显示。