Shell脚本三剑客之Sed和Awk

目录

前言

一、文本三剑客之sed

1.1 sed 介绍

1.2  sed 工作流程

1.3  sed 工作原理

1.4 sed命令常见用法

1.4.1  语法结构

1.4.2  常见的选项

1.4.3  常见的操作

1.5  sed用法示例

1.5.1  输出符合条件的文本(p 表示正常输出)

1.5.2  删除符合条件的文本(d) 

1.5.3  替换符合条件的文本  

 1.5.4  迁移符合条件的文本

 1.5.5  使用脚本编辑文件

1.5.6 分组操作

1.5.7  直接修改文件内容   【 i 】

二、awk

2.1  awk常见用法

2.2 工作原理

2.3  awk  内置变量

2.4   用法示例

2.4.1  awk  基本用法

2.4.2 awk常用内置变量

2.4.3  通过管道、双引号调用 Shell 命令

2.4.4  BEGIN、END

2.4.5  模糊匹配

2.4.6    关于数值与字符串的比较

2.4.7   其他内置变量的用法

2.4.8  调用函数getline

2.4.9   awk的  if语句

2.4.10 awk 也可用于for,while,数组

三、总结


前言

Linux中最重要的三个命令在业界被称为“三剑客”,它们是awk,sed,grep。熟练使用这三个工具可以提升运维效率。这章内容重点讲解sed 和awk 的功能。

一、文本三剑客之sed

1.1 sed 介绍

sed 即 Stream EDitor,是行编辑器

Sed是从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,直到最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(PatternSpace),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现有卡顿的现象,这是因为vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快

sed(Stream EDitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输出处理的某些行。sed 也可以在无交互的情况下实现相当复杂的文本处理操作,被广泛应用于 Shell 脚本中,用以完成各种自动化处理任务。

1.2  sed 工作流程

sed 的工作流程主要包括读取、执行和显示三个过程。

读取:sed 从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。

执行:默认情况下,所有的 sed 命令都在模式空间中顺序地执行,除非指定了行的地址,否则 sed 命令将会在所有的行上依次执行。

显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。

在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出。

1.3  sed 工作原理

Shell脚本三剑客之Sed和Awk_第1张图片

工作原理:

读入新的一行内容到缓存空间;

从指定的操作指令中取出第一条指令,判断是否匹配pattern;

如果不匹配,则忽略后读的编辑命令,回到第2步继续取出下一条指令;

如果匹配,则针对缓存的行执行后续的编辑命令;完成后,回到第2步继续取出下一条指令;

当所有指令都应用之后,输出缓存行的内容;回到第1步继续读入下一行内容;

当所有行都处理完之后,结束;

1.4 sed命令常见用法

通常情况下调用sed命令有两种格式,如下所示。
其中,"参数"是指操作的目标文件,当存在多个操作对象时用,文件之间用逗号" ,"分隔;而 scriptfile表示脚本文件,需要用"-f"选项指定,当脚本文件出现在目标文件之前时,表示通过指定的脚本文件来处理输入的目标文件。

1.4.1  语法结构

sed [选项] '操作' 参数

sed [选项] -f scriptfile 参数

1.4.2  常见的选项

选项

作用

-e或 --expression=

表示用指定命令或者脚本来处理输入的文本文件

-f 或 --file=

表示用指定的脚本文件来处理输入的文本文件

-h 或 --help

显示帮助

-n、--quiet 或 silent

表示仅显示处理后的结果

-i.bak

直接编辑文本文件

-r,-E

使用扩展正则表达式

-s

将多个文件视为独立文件,而不是单个连续的长文件流

1.4.3  常见的操作

"操作"用于指定对文件操作的动作行为,也就是sed的命令。通常情况下是采用的"[n1 [,n2] ]"操作参数的格式。n1、n2是可选的,代表选择进行操作的行数,如操作需要在5~20行之间进行,则表示为"5,20动作行为”。

参数

作用

a

增加,在当前行下面增加一行指定内容

c

替换,将选定行替换为指定内容

d

删除,删除选定的行

i

插入,在选定行上面插入一行指定内容

            p

打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII 码输出。其通常与"一n"选项一起使用

s

替换,替换指定字符

y

字符转换

1.5  sed用法示例

1.5.1  输出符合条件的文本(p 表示正常输出)

输出所有内容,等同于cat   test.txt

Shell脚本三剑客之Sed和Awk_第2张图片输出3~5行

输出所有奇数行,n 表示读入下一行资料

Shell脚本三剑客之Sed和Awk_第3张图片输出所有偶数行,n 表示读入下一行资料

输出第 1~5 行之间的奇数行(第 1、3、5 行)

直接显示第二行内容 

Shell脚本三剑客之Sed和Awk_第4张图片

输出第 10 行至文件尾之间的偶数行

Shell脚本三剑客之Sed和Awk_第5张图片

以上是 sed 命令的基本用法,sed 命令结合正则表达式时,格式略有不同,正则表达式以“/”包围。例如,以下操作是 sed 命令与正则表达式结合使用的示例。

输出包含the 的行

Shell脚本三剑客之Sed和Awk_第6张图片输出从第 4 行至第一个包含 the 的行

输出包含the 的行所在的行号,等号(=)用来输出行号

Shell脚本三剑客之Sed和Awk_第7张图片输出以数字结尾的行

Shell脚本三剑客之Sed和Awk_第8张图片 输出包含单词wood 的行,\<、\>代表单词边界

Shell脚本三剑客之Sed和Awk_第9张图片

1.5.2  删除符合条件的文本(d) 

下面命令中 nl 命令用于计算文件的行数,结合该命令可以更加直观地查看到命令执行的结果。

删除第 3 行

Shell脚本三剑客之Sed和Awk_第10张图片

删除第 3~5 行

Shell脚本三剑客之Sed和Awk_第11张图片

删除包含 cross 的行,原本的第 9 行被删除;

Shell脚本三剑客之Sed和Awk_第12张图片如果要删除不包含 cross 的行,用!符号表示取反操作, 如'/cross/!d' 

  删除以小写字母开头的行

Shell脚本三剑客之Sed和Awk_第13张图片删除以"."结尾的行 

Shell脚本三剑客之Sed和Awk_第14张图片

删除所有空行

Shell脚本三剑客之Sed和Awk_第15张图片

注 意 : 若 是 删 除 重 复 的 空行 , 即 连 续 的 空 行 只 保 留 一 个 , “cat -s test.txt”。 

Shell脚本三剑客之Sed和Awk_第16张图片

1.5.3  替换符合条件的文本  

在使用 sed 命令进行替换操作时需要用到 s(字符串替换)、c(整行/整块替换)、y(字符转换)命令选项,常见的用法如下所示。

将每行中的第一个the 替换为 THE

Shell脚本三剑客之Sed和Awk_第17张图片

 将每行中的第 2 个 l 替换为 L

Shell脚本三剑客之Sed和Awk_第18张图片

将文件中的所有o 删除(替换为空串)

Shell脚本三剑客之Sed和Awk_第19张图片在每行行首插入#号

Shell脚本三剑客之Sed和Awk_第20张图片

 在每行行尾插入字符串EOF

Shell脚本三剑客之Sed和Awk_第21张图片

将包含the 的所有行中的 o 都替换为 O

插入符合条件的行使用-i  表示在行的前面插入一个新行

Shell脚本三剑客之Sed和Awk_第22张图片

 使用-i.bak 可以使要编辑的文本进行备份

Shell脚本三剑客之Sed和Awk_第23张图片

 1.5.4  迁移符合条件的文本

在使用 sed 命令迁移符合条件的文本时,常用到以下参数.
H:复制到剪贴板;
g、G:将剪贴板中的数据覆盖/追加至指定行;
w:保存为文件;
r:读取指定文件;
a:追加指定内容。具体操作方法如下所示。
I,i : 忽略大小写

案例:

将包含the 的行迁移至文件末尾,    {;}用于多个操作

Shell脚本三剑客之Sed和Awk_第24张图片

将第 1~5 行内容转移至第 7 行后 

Shell脚本三剑客之Sed和Awk_第25张图片

 将包含the 的行另存为文件 out.txt

Shell脚本三剑客之Sed和Awk_第26张图片

将文件/etc/hostname 的内容添加到包含 the 的每行以后

Shell脚本三剑客之Sed和Awk_第27张图片在第 3 行后插入一个新行,内容为New

Shell脚本三剑客之Sed和Awk_第28张图片

在第 3 行后插入多行内容,中间的\n 表示换行 

 在包含the 的每行后插入一个新行,内容为 New

Shell脚本三剑客之Sed和Awk_第29张图片

 1.5.5  使用脚本编辑文件

使用 sed 脚本将多个编辑指令存放到文件中(每行一条编辑指令),通过“-f”选项来调用

例如执行以下命令即可将第 1~5 行内容转移至第 16 行后。

方法一:sed 命令   sed '1,5{H;d};16G' test.txt    //将第 1~5 行内容转移至第 16 行后

Shell脚本三剑客之Sed和Awk_第30张图片

方法二:脚本方法:将多个编辑指令存放到文件中(每行一条编辑指令),通过“-f”选项来调用

Shell脚本三剑客之Sed和Awk_第31张图片

Shell脚本三剑客之Sed和Awk_第32张图片

1.5.6 分组操作

当我们需要对一行数据进行多次操作的时候我们可以使用{}进行分组 

Shell脚本三剑客之Sed和Awk_第33张图片 当我们运行多个命令时也可以使用选项  -e  来表示

Shell脚本三剑客之Sed和Awk_第34张图片

注:-e 可以将多个命令连接起来,也可以将多个编辑命令保存到文件中,通过 -f 指定文件,以完成多个处理操作。 

1.5.7  直接修改文件内容   【 i 】

在每一行的开头插入#号,直接修改原文件

Shell脚本三剑客之Sed和Awk_第35张图片

将每一行的开头#号删除,直接修改原文件 

Shell脚本三剑客之Sed和Awk_第36张图片

编写一个脚本,用来调整vsftpd 服务配置,要求禁止匿名用户,但允许本地用户(也允许写入)。

Shell脚本三剑客之Sed和Awk_第37张图片

Shell脚本三剑客之Sed和Awk_第38张图片

二、awk

在 Linux/UNIX 系统中,awk 是一个功能强大的编辑工具,逐行读取输入文本,并根据指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理,可以在无交互的情况下实现相当复杂的文本操作,被广泛应用于 Shell 脚本,完成各种自动化配置任务。

20世纪70年代诞生于贝尔实验室,现在centos7用的是gawk,之所以叫AWK 是因为其取了三位创始人 Alfred  Aho, Peter   Weinberger 和  Brian  Kernighan  的 family  name 的首字符。

2.1  awk常见用法

通常情况下 awk 所使用的命令格式如下所示,其中,单引号加上大括号“{}”用于设置对数据进行的

处理动作。awk 可以直接处理目标文件,也可以通过“-f”读取脚本对目标文件进行处理。

格式:

awk 选项 '模式或条件 {编辑指令}' 文件 1 文件 2 „         //过滤并输出文件符条件的内容

awk -f 脚本文件 文件 1 文件 2 „          //从脚本中调用编辑指令,过滤并输出内容

前面提到 sed 命令常用于一整行的处理,而 awk 比较倾向于将一行分成多个“字段”然后再进行处理,且默认情况下字段的分隔符为空格或者 tab 键。awk 执行结果可以通过 print 的功能将字段数据打印显示。

    在使用 awk 命令的过程中,可以使用逻辑操作符“&&”,表示“与”, “||”表示“或”,“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别 表示加、减、乘、除、取余和乘方。

awk 从输入文件或者标准输入中读入信息,与 sed 一样,信息的读入也是逐行读取的。

不同的是 awk 将文本文件中的一行视为一个记录,而将一行中的某一部分(列)作为记录中的一个字段(域)

为了操作这些不同的字段,awk 借用 shell 中类似于位置变量的方法, 用**$1、$2、$3„顺序地表示行(记录)中的不同字段**。另外 awk 用$0 表示整个行(记录)

不同的字段之间是通过指定的字符分隔

awk 默认的分隔符是空格

awk 允许在命令行中用“-F 分隔符”的形式来指定分隔符

2.2 工作原理

逐行读取文本,默认以空格为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模

式或着条件执行编辑命令。

awk 命令对/etc/passwd 文件的处理过程图:

Shell脚本三剑客之Sed和Awk_第39张图片

2.3  awk  内置变量

awk 包含几个特殊的内建变量(可直接用):

变量

解释

FS

指定每行文本的字段分隔符,默认为空格或制表位(tab)

NF

当前处理的行的字段个数

NR

当前处理的行的行号(序数)

$0

当前处理的行的整行内容

$n

当前处理行的第 n 个字段(第 n 列)

FILENAME

被处理的文件名

RS

数据记录分隔,默认为\n,即每行为一条记录(\n表示回车)

2.4   用法示例

2.4.1  awk  基本用法

输出所有内容

Shell脚本三剑客之Sed和Awk_第40张图片

或者  awk '{print $0}' shuiguo.txt //输出所有内容,等同于 cat   shuiguo.txt

Shell脚本三剑客之Sed和Awk_第41张图片

以冒号作为分割符,显示出第五列的内容

Shell脚本三剑客之Sed和Awk_第42张图片  注:awk默认把这一行当做一列,因为没有被空格分隔,awk默认以空格或tab键分隔

打印出第1和第3列

Shell脚本三剑客之Sed和Awk_第43张图片

注:显示一个空格,空格需要用双引号引起来,如果不用引号默认以变量看待,如果是常量就需要双引号引起来

Shell脚本三剑客之Sed和Awk_第44张图片

用制表符作为分隔符输出

Shell脚本三剑客之Sed和Awk_第45张图片

 定义多个分隔符,只要看到其中一个都算作分隔符

Shell脚本三剑客之Sed和Awk_第46张图片

2.4.2 awk常用内置变量

$1:代表第一列
$2:代表第二列以此类推
$0:代表整行
NF:一行的列数
NR:行数

打印包含root的整行内容

打印包含root的行的第一列和第六列

打印每一行的列数

Shell脚本三剑客之Sed和Awk_第47张图片

显示行号  使用NR参数

Shell脚本三剑客之Sed和Awk_第48张图片

 显示出每行的行号和内容

Shell脚本三剑客之Sed和Awk_第49张图片

 打印第二行

Shell脚本三剑客之Sed和Awk_第50张图片

 打印第二行的第一列

打印最后一列

Shell脚本三剑客之Sed和Awk_第51张图片

 打印总行数   END 表示汇总的意思

打印文件最后一行

显示出文件第几行有几列

Shell脚本三剑客之Sed和Awk_第52张图片

2.4.3  通过管道、双引号调用 Shell 命令

操作命令放在{}中

管道符号前面的命令输出的内容交给管道符号后面的命令处理

结合正则表达式,正则表达式同样要被/包围

调用的shell命令需要用""引起来

{}中多个命令之间也能过;分隔

调用wc -l 命令统计使用bash的用户个数(双引号之间直接调命令"wc -l")等同于 grep -c “bash$” /etc/passwd

 统计以冒号分隔的文本段落数,END{ }语句块中,往往会放入打印结果等语句

Shell脚本三剑客之Sed和Awk_第53张图片

 查看当前内存使用百分比

Shell脚本三剑客之Sed和Awk_第54张图片

 网卡的ip、流量

Shell脚本三剑客之Sed和Awk_第55张图片

2.4.4  BEGIN、END

逐行执行开始之前执行什么任务,结束之后再执行什么任务

BEGIN一般用来做初始化操作,仅在读取数据记录之前执行一次
END一般用来做汇总操作,仅在读取完数据记录之后执行一次

 如果不用引号awk就当作一个变量来输出了,所以不需要加$了

 注:BEGIN在处理文件之前,所以后面不跟文件名也不影响

BEGIN亦可以进行运算

Shell脚本三剑客之Sed和Awk_第56张图片先写’BEGIN{x=0}; ;END{print x}’ ,然后再写中间的匹配// 以/bin/bash结尾 ,因为/有其他匹配的意思,要加转义符号\ ,最后再加{x++},转到下一行

Shell脚本三剑客之Sed和Awk_第57张图片

扩展:

BEGIN语句块在awk开始从输入流中读取行之前被运行,这是一个可选的语句块,比方变量初始化、打印输出表格的表头等语句通常能够写在BEGIN语句块中。

END语句块在awk从输入流中读取全然部的行之后即被运行。比方打印全部行的分析结果这类信息汇总都是在END语句块中完毕,它也是一个可选语句块。

pattern语句块中的通用命令是最重要的部分,它也是可选的。假设没有提供pattern语句块,则默认运行{ print },即打印每个读取到的行。awk读取的每一行都会运行该语句块。

这三个部分缺少任何一部分都可以

2.4.5  模糊匹配

用~表示包含,!~表示不包含

模糊匹配,只要有ro就匹配上

Shell脚本三剑客之Sed和Awk_第58张图片匹配结尾不是nologin的行可以使用  ! 取反操作

Shell脚本三剑客之Sed和Awk_第59张图片

2.4.6    关于数值与字符串的比较

比较符号:==      !=       <=       >=      <       >

打印出第五行的内容

Shell脚本三剑客之Sed和Awk_第60张图片

 进行精确匹配  一定是root

打印出行号小于5的行

打印出第3列大于等于1000的行,以冒号作为分隔符 

Shell脚本三剑客之Sed和Awk_第61张图片

 逻辑运算    &&(表示且)    ||   (表示或)

打印出第3列小于10或大于1000的行

Shell脚本三剑客之Sed和Awk_第62张图片打印出行号4到9的行

Shell脚本三剑客之Sed和Awk_第63张图片

 打印1-200之间所有能被7整除并且包含数字7的整数数字

Shell脚本三剑客之Sed和Awk_第64张图片

2.4.7   其他内置变量的用法

FS、OFS、NR、FNR、RS、ORS

FS:输入字段的分隔符 默认是空格
OFS:输出字段的分隔符 默认也是空格

NR :  当前处理行的行号,从1开始
FNR:读取文件的记录数(行号),从1开始,新的文件重新重1开始计数


RS:输入行分隔符  默认为换行符
ORS:输出行分隔符  默认也是为换行符

在打印之前定义字段分隔符为冒号

Shell脚本三剑客之Sed和Awk_第65张图片

 OFS定义了输出时以什么分隔,$1$2中间要用逗号分隔,因为逗号默认被映射为OFS变量,而这个变量默认是空格

Shell脚本三剑客之Sed和Awk_第66张图片

 使用FNR的行号可以在追加当有多个文件时,分别列出每个文件的行号数,新的文件都是从1开始的,而NR是列出的行号数是从1开始,不会分别列出各个文件

Shell脚本三剑客之Sed和Awk_第67张图片

 RS:指定以什么为换行符,这里指定是冒号,你指定的肯定是原文里存在的字符

Shell脚本三剑客之Sed和Awk_第68张图片把多行合并成一行输出,输出的时候自定义以空格分隔每行,本来默认的是回车键

Shell脚本三剑客之Sed和Awk_第69张图片

2.4.8  调用函数getline

定义引用变量

 awk直接定义变量并引用

 调用函数getline,读取一行数据的时候并不是得到当前行而是当前行的下一行

Shell脚本三剑客之Sed和Awk_第70张图片显示奇偶数行

Shell脚本三剑客之Sed和Awk_第71张图片

2.4.9   awk的  if语句

awk的if语句也分为单分支、双分支和多分支

单分支为if(){}
双分支为if(){}else{}
多分支为if(){}else if(){}else{}

第三列小于10的打印整行

Shell脚本三剑客之Sed和Awk_第72张图片

第三列小于10的打印第三列,否则打印第一列

Shell脚本三剑客之Sed和Awk_第73张图片

2.4.10 awk 也可用于for,while,数组

写一个while 循环,来测定行数,去除上面地9行内容,得到分区数

Shell脚本三剑客之Sed和Awk_第74张图片

案例:$1=$1是用来激活$0的重新赋值,也就是说字段$1...和字段数NF的改变会促使awk重新计算$0的值,通常是在改变OFS后而需要输出$0时这样做

Shell脚本三剑客之Sed和Awk_第75张图片

案例:数组

 

awk 'BEGIN{a[0]=10;a[1]=20;print a[1]}'
awk 'BEGIN{a[0]=10;a[1]=20;print a[0]}'
awk 'BEGIN{a["abc"]=10;a["xyz"]=20;print a["abc"]}'
awk 'BEGIN{a["abc"]=10;a["xyz"]=20;print a["xyz"]}'
awk 'BEGIN{a["abc"]="aabbcc";a["xyz"]="xxyyzz";print a["xyz"]}'
awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a){print i,a[i]}}' 

Shell脚本三剑客之Sed和Awk_第76张图片

三、总结

1. sed工具除了调用文件或脚本执行命令,否则命令都需要加上' ' 符号

即:调用 sed 命令有两种格式

sed[选项] '操作' 参数
sed [选项] -f scriptfile 参数
其中,“参数”是指操作的目标文件,当存在多个操作对象时用,文件之间用逗号“,”分隔;

而 scriptfile 表示脚本文件,需要用“-f”选项指定,当脚本文件出现在目标文件之前时,表示通过指定的脚本文件来处理输入的目标文件

-n选项在符合条件输出和结合正则表达式的时候使用

{}用于奇数行和偶数行的筛选或者奇数行和偶数号的其他操作

sed 命令结合正则表达式时,格式略有不同,正则表达式以“/”包围

使用sed删除命令时,nl 命令用于计算文件的行数,结合该命令可以更加直观地查看到命令执行的结果,而不使用-n

2. sed操作指令置于’'中,awk比sed多一个{}

sed[选项] '操作' 参数
awk 选项 '模式或条件 {编辑指令}' 文件 1 文件 2

 

w,who,whoami,who am i

w 显示已经登录的用户及正在进行的操作
who 显示已经登录的用户名、终端名称、登录时间及登录IP
whoami 显示当前用户的用户名
who am i 显示登录系统的时候的用户名,即使已经切换到其他用户也显示登录时的用户
一般输出关于段,列的信息使用awk,其他的使用sed或grep更加方便

awk  输出的奇偶行都使用绝对路径
sed   输出的奇偶行都使用相对路径

使用awk调用shell命令,统计数量时,n是个变量,可自定义
若没有定义n的初始值,则n=0

awk判断条件中双引号之间的内容,如果有特殊符号不需要使用转义符

FS在{}中间使用,F在{}外面使用

你可能感兴趣的:(linux,unix)