当前位置: 首页 > news >正文

从 0 到 1 学 sed 与 awk:Linux 文本处理的两把 “瑞士军刀”

一、SED是什么 

1.1

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

二、sed 的原理


sed 的工作流程主要包括读取、执行和显示三个过程。
读取:sed 从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。


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


显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。
在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

常见的 sed 命令选项主要包含以下几种。
-e 或--expression=:表示用指定命令或者脚本来处理输入的文本文件。
-f 或--file=:表示用指定的脚本文件来处理输入的文本文件。
-h 或--help:显示帮助。
-n、--quiet 或 silent:表示仅显示处理后的结果。
-i.bak:直接编辑文本文件。
-r, -E 使用扩展正则表达式
-s  将多个文件视为独立文件,而不是单个连续的长文件流

三、sed命令用法 

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

输出所有内容,等同于 cat demo

sed -n '3p' demo //输出第 3 行

sed -n '3,5p' demo //输出 3~5 行

sed -n 'p;n' demo  输出所有奇数行,n 表示读入下一行资料

  

sed -n 'n;p' demo   输出所有偶数行,n 表示读入下一行资料

sed -n '1,5{p;n}' demo  输出第 1~5 行之间的奇数行(第 1、3、5 行)

sed -n '10,${n;p}' demo   输出第 10 行至文件尾之间的偶数行

ifconfig ens33|sed -n 2p   #直接显示第二行内容

sed 命令与正则表达式相结合 

sed -n '/the/p' demo      //输出包含the 的行

sed -n '4,/the/p' demo //输出从第 4 行至第一个包含 the 的行

sed -n '/the/=' demo

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

sed -n '/^PI/p' demo //输出以PI 开头的行

sed -n '/[0-9]$/p' demo //输出以数字结尾的行

sed -n '/\<wood\>/p' demo   //输出包含单词wood 的行

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

nl demo | sed '3d' //删除第 3 行

nl demo | sed '3,5d' //删除第 3~5 行

nl demo |sed '/cross/d' //删除匹配所有包含 cross 的行。

sed '/\.$/d' demo //删除以"."结尾的行 

sed '/^$/d' demo //删除所有空行

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

3.3 替换符合条件的文本

sed 's/the/THE/' demo //将每行中的第一个the 替换为 THE

sed 's/l/L/2' demo //将每行中的第 2 个 l 替换为 L

sed 's/o//g' demo //将文件中的所有o 删除(替换为空串)

sed 's/^/#/' demo //在每行行首插入#号

3.4 迁移符合条件的文本

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

示例:

sed '/the/{H;d};$G' demo //将包含the 的行迁移至文件末尾,{;}用于多个操作

sed '1,5{H;d};17G' demo //将第 1~5 行内容转移至第 17 行后 

sed '/the/w out.file' demo //将包含the 的行另存为文件 out.file

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

sed '3aNew' demo //在第 3 行后插入一个新行,内容为New

sed '/the/aNew' demo //在包含the 的每行后插入一个新行,内容为 New

sed '3aNew1\nNew2' demo  在第 3 行后插入多行内容,中间的\n 表示换行

四、awk分析文本工具

4.1 awk 是什么

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
它是专门为文本处理设计的编程语言,也是行处理软件,通常用于扫描、过滤、统计汇总工作
数据可以来自标准输入也可以是管道或文件
20世纪70年代诞生于贝尔实验室,现在centos7用的是gawk

之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。 

4.2 awk工作原理

当读到第一行时,匹配条件,然后执行指定动作,再接着读取第二行数据处理,不会默认输出,如果没有定义匹配条件默认是匹配所有数据行,awk隐含循环,条件匹配多少次动作就会执行多少次逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。

sed命令常用于一整行的处理,而awk比较、倾向于将一行分成多个""字段"然后再进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。在使用awk命令的过程中,可以使用逻辑操作符" &&"表示"与"、"||表示"或"、"!"表示非";还可以进行简单的数学运算,如+、一、*、/、%、^分别表示加、减、乘、除、取余和乘方。


4.2.1工作流程

pattern [ˈpætn] 模式 ; process [ˈprəʊses] 处理

任何 awk 语句都是由模式和动作组成,一个 awk 脚本可以有多个语句。模式决定动作语句的触发条件

和触发时间。

在 linux 上常用的是 gawk,awk 是 gawk 的链接文件

awk---->gawk 即: gun awk

[root@benet22 opt]# which awk

/usr/bin/awk

[root@benet22 opt]# ll `which awk`

lrwxrwxrwx. 1 root root 4 8月 19 2022 /usr/bin/awk -> gawk

4.2.2 执行流程

BEGIN 语句设置计数和打印头部信息,在任何动作之前进行

END 语句输出统计结果,在完成动作之后执行

AWK执行的流程非常简单:读(Read)、执行(Execute)与重复

4.3基本语法

awk 选项' 模式或条件{操作}' 文件1 文件2 ...

awk -f 脚本文件 文件1 文件2 ..

格式:awk关键字 选项 命令部分 '{xxxx}' 文件名

**AWK 支持两种不同类型的变量:内建变量(可直接使用),自定义变量awk 内置变量(预定义变量)

FS:指定每行文本的字段分隔符,默认为空格或制表位。

NF:当前处理的行的字段个数。在执行过程中对应于当前的字段数,NF:列的个数

NR:当前处理的行的行号(序数)。 在执行过程中对应于当前的行号

$0:当前处理的行的整行内容。

$n:当前处理行的第 n 个字段(第 n 列)。比如: $1 表示第一个字段,$2 表示第二个字段

FILENAME:被处理的文件名(当前输入文件的名)。

FNR 各文件分别计数的行号

OFS 输出字段分隔符(默认值是一个空格)

ORS 输出记录分隔符(默认值是一个换行符)

RS:行分隔符。awk从文件上读取资料时,将根据Rs的定义把资料切割成许多条记录, 而awk一次仅读

入一条记录,以进行处理。预设值是" \n'

5、实战案列

5.1案例文本

awk '{print "hello"}' < /etc/passwd    #/etc/passwd中文件的内容有多少行“hello”就打印多少次

awk '{print}' zz 

awk '{print $1}' zz

awk -F: '{print $5}' zz   //自定义冒号为分隔符显示分隔之后的第五列

awk -Fx '{print $1}' /etc/passwd

awk -F: '{print $1,$2}' zz1

5.2 内建变量


awk常用内置变量:$1、$2、NF、NR、$0

$1:代表第一列

$2:代表第二列以此类推

$0:代表整行

NF:一行的列数

NR:行数

示例一

awk 'NR==2' /etc/passwd   //打印第二行,不加print也一样,默认就是打印

awk -F: 'NR==2{print $1}' /etc/passwd    打印第二行的第一列

awk -F: '{print $NF}' /etc/passwd  //打印最后一列

awk  -F: '{print "当前行有"NF"列"}' zz

 awk -F: '{print "第"NR"行有"NF"列"}' /etc/passwd    //第几行有几列 

5.3 BEGIN END 运算


逐行执行开始之前执行什么任务,结束之后再执行什么任务,用BEGIN、END
BEGIN一般用来做初始化操作,仅在读取数据记录之前执行一次
END一般用来做汇总操作,仅在读取完数据记录之后执行一次

5.3.1 awk的运算

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

awk 'BEGIN{x=10;print x+1}'  BEGIN在处理文件之前,所以后面不跟文件名也不影响

awk 'BEGIN{print 2.5+3.5}'   //小数也可以运算

awk 'BEGIN{print 3*4}'

^和**都是幂运算

5.3.2 模糊匹配

模糊匹配,用~表示包含,!~表示不包含

awk -F: '/root/' /etc/passwd    

#如果后面有具体打印多少列就没法省略print了

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

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

5.3.4 逻辑运算

&& 和 || 是逻辑运算符,用于组合多个条件并控制程序流程。

&& 要求所有条件都为真时才为真,否则为假。

|| 只要有一个条件为真就为真,全为假时才为假。

5.3.5 BEGIN END 流程


其他内置变量的用法FS(输入)、OFS、NR、FNR、RS、ORS

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

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

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

RS:输入行分隔符 默认为换行符

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

awk 'BEGIN{FS=":"}{print $1}' pass.txt     //在打印之前定义字段分隔符为冒号

5.4 awk高级用法 if语句

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

awk -F: '{if($3<10){print $0}}' /etc/passwd   //第三列小于10的打印整行


文章转载自:

http://ftc3nteV.ygrwt.cn
http://8RPctokJ.ygrwt.cn
http://DO5OMHac.ygrwt.cn
http://19lTZgk1.ygrwt.cn
http://tQJ5W2Z0.ygrwt.cn
http://39lZ0tkh.ygrwt.cn
http://3BPq1Hi9.ygrwt.cn
http://FCx0ZhfA.ygrwt.cn
http://J8AOVgDw.ygrwt.cn
http://cjxH5vyV.ygrwt.cn
http://EUdUpXKj.ygrwt.cn
http://YTyMriMX.ygrwt.cn
http://ZsA6e3RF.ygrwt.cn
http://eS0gb9Xg.ygrwt.cn
http://EOXAZxOe.ygrwt.cn
http://CmmN7ZtZ.ygrwt.cn
http://K70Hnmqr.ygrwt.cn
http://D98Cb0No.ygrwt.cn
http://SeTca4gZ.ygrwt.cn
http://Y7VuSX3T.ygrwt.cn
http://lrZrlnaI.ygrwt.cn
http://tOgBeAd4.ygrwt.cn
http://N6AOlhzu.ygrwt.cn
http://dG5tPrtk.ygrwt.cn
http://F7Sukd3M.ygrwt.cn
http://WiuM5t3g.ygrwt.cn
http://XooUE2jA.ygrwt.cn
http://12PXbmqW.ygrwt.cn
http://7I3FFTJe.ygrwt.cn
http://jgOj8b2v.ygrwt.cn
http://www.dtcms.com/a/368378.html

相关文章:

  • VNC连接服务器实现远程桌面-针对官方给的链接已经失效问题
  • 【Web】理解CSS媒体查询
  • 编写前端发布脚本
  • 无密码登录与设备信任:ABP + WebAuthn/FIDO2
  • 消息队列-ubutu22.04环境下安装
  • Vue3源码reactivity响应式篇之EffectScope
  • 从Java全栈到前端框架:一位程序员的实战之路
  • 【Java实战㉖】深入Java单元测试:JUnit 5实战指南
  • 【AI论文】Robix:一种面向机器人交互、推理与规划的统一模型
  • C++(Qt)软件调试---bug排查记录(36)
  • yolov8部署在一台无显卡的电脑上,实时性强方案
  • Alibaba Cloud Linux 3 安装Docker
  • SQL面试题及详细答案150道(61-80) --- 多表连接查询篇
  • 详细解读Docker
  • 【OJ】C++ vector类OJ题
  • 【数据库】MySQL 数据库创建存储过程及使用场景详解
  • Ubuntu22.04-ROS2下navgation2编译到运行
  • OpenLayers常用控件 -- 章节四:图层控制与切换教程
  • [ubuntu][C++]onnxruntime安装cpu版本后测试代码
  • 一个专为地图制图和数据可视化设计的在线配色网站,可以助你制作漂亮的地图!
  • 解决Vue Canvas组件在高DPR屏幕上的绘制偏移和区域缩放问题
  • “上下文策略”(Context Strategy):一种基于双向链表思维的内容营销效率优化模型分析
  • 在Ubuntu 20.04的服务器上查找的服务器的IP地址
  • 用 Cursor AI 快速开发你的第一个编程小程序
  • 自动化运维-ansible中对roles的创建与使用
  • 《Ceph集群数据同步异常的根因突破与恢复实践》
  • 从零开始的云计算生活——第五十九天,基于Jenkins自动打包并部署Tomcat环境
  • 串口通信的学习
  • 企业为何仍困在“数据孤岛”?——从iPaaS重构信息流的实践路径
  • MySQL 主从复制详解:部署与进阶配置