AWK语言第二版 2.2选择

2.2 选择

Awk的基本结构组成,就是用一系列的样式选择出感兴趣的行,并对其进行操作。这样的程序很多都是一次性的,敲出来之后就用几次。然而,有些程序很有用,如果每次用之前都要重新敲一遍代码,就太麻烦了,所以值得将它们存到脚本里,以便有需要随时使用。

下面有些例子,与现有的Unix工具功能上是重复的,之所以把它们放在这里讨论,更多地是为了讲解Awk,而不是要取代这些工具,当然Awk的灵活性意味着你可以定制自己所需的特殊版本。(而且你能用Awk做出在多个Unix发行版之间可移植的版本,当这些工具在不同Unix发行版间存在差异的时候)。比如,Unix命令 head 默认会打出前10行,这与另一个简单的 sed 命令 10q 是等价的。下面的一行Awk程序也有同样的功能:

NR <= 10

然而,如果输入量特别大,上面的程序就很低效,因为它会读入所有输入,但在第十行之后就啥都不干了。改进后的版本会输出所有行,但在第十行之后退出:

{ print }
NR > 10 { exit }

原始版本的运行时间与输入长度成正比,而改进后的版本只会用固定很短的时间。

如果你只想打印输入的前三行和后三行该怎么做呢?(假如你有个按出现次数排序的列表,你只想看出现最多和最少的值。) 一个简单的办法是将所有输入都保存下来,只打印所需的行:

awk '{ line[NR] = $0 }
END { for (i = 1; i <= 3; ++i) print line[i]print "..."for (i = NR -2; i <= NR; ++i) print line[i]} ' $*

如果输入行小于7行,这个程序会有问题,但作为个人使用的工具,只要你使用时记得它的限制,也许就没啥大不了的。

虽然只打印一小部分,但这个程序会将所有输入都保存下来,因此输入为大文件时可能就会很慢。还有一个办法,就是先把前三行打出来,然后永远只保存最近的三行,在结束时打出来:

awk 'NR <= 3 { print; next }{ line[1] = line[2]; line[2] = line[3]; line[3] = $0 }END { print "..." for (i = 1; i <= 3; ++i) print line[i] } ' $*

next 语句会结束当前记录(当前行)的处理,并重新回到程序开头,处理下一行。(注:可以将 next 类比为C语言的continue,即跳过下面的语句,重新开始循环——在Awk里是重新读入一行。在这个例子里面,next跳过的就是第二行的代码

不过令人诧异的是,这个版本比前一个版本还慢了大约三分之一,估计是因为做了太多的行拷贝操作。第三个办法,是将输入作为环形缓冲区:只保留三行,而且仅对最后三行做索引的轮转(1变2,2变3,3变1),这样就不会有多余的拷贝操作了:

awk ' NR <= 3 { print; next }{ line[NR%3] = $0 }
END { print "..."i = (NR+1) % 3for (j = 0; j < 3; ++j) {print line[i]i = (i+1) % 3} 
} ' $*

经过实测,这个版本也仅比第一个版本快了一点点,而这微小的提升,代价是END块里面有些复杂的索引处理。为此增加的复杂度是不值的,因为这样的程序处理一百万行的输入文件,也就只要几秒钟。

是实时处理输入,还是将输入保存到数组中最后用END来处理,两者之间需要权衡。幸运的是,现代的处理器够快,内存够大,因此通常都是从尽可能简单的代码开始写起,而不是一开始就试图去节省cpu时间或内存空间。当然,这也是我们处理问题的方式:先用简单快速的方法,除非必要,后面再用更复杂的方法。

有时也要丢弃前面n行,并打印剩余的行;比如有个带表头的文件,而你需要跳过表头来处理表内的数据:

awk ' NR > 1'

前面说过Unix有个工具叫 head,对应地还有个 tail,就是用来输出文件的最后n行。但如果你要将最后n行倒序输出呢?这时你自己写的工具就派上用场了,因为并不是所有的版本都会提供你需要的选项。下面是个简单实现的版本:

awk '{ line[NR] = $0 }END { for (i = NR; i > NR-3; i--) print line[i] } ' $*

如果把上面的 i > NR -3 替换成 i > 0,就能对整个文件进行倒序输出。

练习2-1:修改“打印前几行后几行”的程序,使之能正确处理更短的输入。

练习2-2:改进最后一个样例,支持把需要打印的行数作为参数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/75169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux修改fs.inotify.max_user_watches(“外部文件更改同步可能很慢”和“当前的 inotify(7) 监视限制太低”)

fs.inotify.max_user_watches 参数是用于控制 Linux 内核中 inotify 子系统的观察者数量限制。inotify 是一种文件系统监控机制&#xff0c;它可以用于检测文件或目录的变化&#xff0c;并在事件发生时通知相关的应用程序。 具体而言&#xff0c;fs.inotify.max_user_watches …

B站:AB test [下]

Focus在&#xff1a;AB Test结束后&#xff0c;如何进行显著性检验&#xff1f;&#xff08;以判断改动是否有效果&#xff09; 引入&#xff1a;Z检验和T检验 而T检验适用于 n<30 的小样本 值得注意的是&#xff1a;统计上显著并不意味着现实中显著&#xff01; e.g. 加速…

尚硅谷大数据项目《在线教育之离线数仓》笔记008

视频地址&#xff1a;尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 P123 P124 P125 P126 P127 P128 P129 P123 Apache Superset是一个现代的数据探索和可视化平台。它功能强大且十分易用&#xff0c;可对接各种数据源&#xff0c;包括很多现代的大数…

设计模式的六大设计原则

一、单一职责原则 一个类只负责一个单一明确的职责。如果一个类同时负责多个职责&#xff0c;来自职责A的需求变更引起的修改可能会导致职责B的功能发生故障。 比如说一个类T原本是符合单一职责的&#xff0c;后来因为某种原因或者是需求变更了&#xff0c;需要将职责P细分为…

医院空调冷热源设计方案VR元宇宙模拟演练的独特之处

作为一个备受关注的技术-元宇宙&#xff0c;毋庸置疑的是&#xff0c;因为建筑本身契合了时尚、前卫、高端、虚拟、科幻、泛在、协作、互通等元素特征&#xff0c;因此在建筑行业更需要元宇宙&#xff0c;以居民建筑环境冷热源设计来说&#xff0c;元宇宙会打破既定的现实阻碍和…

D1D2. Candy Party

d1的题意是有n个人每个人都有一定的糖果&#xff0c;同时每个人必须给其他人一次糖果和接收其他人给他的一次糖果&#xff0c;同时给出的糖果和接收的数目都是2^x&#xff0c;最后确保每个人拥有的糖果数目一样 思路&#xff1a;我们可以先由平均数算出每个人最终要拥有的糖果…

LVS NAT模式负载均衡群集部署

目录 1 群集(集群) cluster 1.1 群集的类型 2 LVS的工作模式及其工作过程 2.1 NAT模式&#xff08;VS-NAT&#xff09; 2.2 直接路由模式&#xff08;VS-DR&#xff09; 2.3 IP隧道模式&#xff08;VS-TUN&#xff09; 3 LVS-NAt 模式配置步骤 3.1 部署共享存储 3.2 配…

SSL证书验签时要带www吗?

单域名证书&#xff1a;顶级域名如www.abc.com或abc.com 不管你提交订单的时候填写的域名是带www或不带www的域名&#xff0c;签发的证书均支持www和不带www的域名 单域名证书&#xff1a;子域名如mail.abc.com&#xff0c;签发的证书仅支持mail.abc.com 通配符证书&#xff…

MySQL触发器使用指南大全

一、介绍 触发器是与表有关的数据库对象&#xff0c;指在insert/update/delete之前或之后&#xff0c;触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性&#xff0c;日志记录&#xff0c;数据校验等操作。 使用别名OLD和NEW来引…

工程管理系统简介 工程管理系统源码 java工程管理系统 工程管理系统功能设计

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管…

C++之生成key-value键值三种方式(一百九十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Linux命令(77)之curl

linux命令之curl 1.curl介绍 linux命令之curl是一款强大的http命令行工具&#xff0c;它支持文件的上传和下载&#xff0c;是综合传输工具。 2.curl用法 curl [参数] [url] curl参数 参数说明-C断点续传-o <filename>把输出写到filename文件中-x在给定的端口上使用HT…

Web server failed to start. Port 8080 was already in use.之解决方法

问题&#xff1a; Web server failed to start. Port 8080 was already in use&#xff0c;这句错误描述意思是当前程序的端口号8080被占用了&#xff0c;需要将占用该端口的程序停止掉才行&#xff1b;错误如图所示&#xff1a; 解决方法&#xff1a; 按住winr&#xff0c;输入…

React 消息文本循环展示

需求 页面上有个小喇叭&#xff0c;循环展示消息内容 逻辑思路 设置定时器&#xff0c;修改translateX属性来实现滚动&#xff0c;判断滚动位置&#xff0c;修改list位置来实现无限滚动 实现效果 代码 /** Author: Do not edit* Date: 2023-09-07 11:11:45* LastEditors: …

android studio的Android Drawable Preview

Android Drawable Preview 应用后&#xff0c;如下图&#xff1a; 再也不用一个一个点开去看了 其他学习资料&#xff1a; 1、付费专栏《Android kotlin入门到进阶系列讲解》&#xff1a;https://blog.csdn.net/qq_35091074/category_11036895.html 2、免费专栏《Android kot…

【大虾送书第九期】速学Linux:系统应用从入门到精通

目录 &#x1f36d;写在前面 &#x1f36d;为什么学习Linux系统 &#x1f36d;Linux系统的应用领域 &#x1f36c;&#xff11;.Linux在服务器的应用 &#x1f36c;&#xff12;.嵌入式Linux的应用 &#x1f36c;&#xff13;.桌面Linux的应用 &#x1f36d;Linux的版本选择 &a…

使用PHPStudy在本地快速建立网站并实现局域网外访问(无公网IP)

文章目录 使用工具1. 本地搭建web网站1.1 下载phpstudy后解压并安装1.2 打开默认站点&#xff0c;测试1.3 下载静态演示站点1.4 打开站点根目录1.5 复制演示站点到站网根目录1.6 在浏览器中&#xff0c;查看演示效果。 2. 将本地web网站发布到公网2.1 安装cpolar内网穿透2.2 映…

高教社杯数模竞赛特辑论文篇-2018年B题:智能 RGV 的动态调度策略(附获奖论文及MATLBA和JAVA代码)(代码篇2)

本文代码较多,分为多篇来写,其他篇详见 智能 RGV 的动态调度策略(附获奖论文及MATLBA代码) 智能 RGV 的动态调度策略(附获奖论文及MATLBA和JAVA代码)(代码篇1)

无涯教程-JavaScript - IMPOWER函数

描述 IMPOWER函数以x yi或x yj文本格式返回加到幂的复数。求幂的复数的计算方法如下- $$(x yi)^ n r ^ ne ^ {n \theta} r ^ n \cos n \theta ir ^ n sin n \theta $$ 哪里- $$r \sqrt {x ^ 2 y ^ 2} \:\:和\:\:\theta \tan ^ {-1} \left(\frac {y} {x} \right)\:…

数字 IC 设计职位经典笔/面试题(四)

共100道经典笔试、面试题目&#xff08;文末可全领&#xff09; 画出 CMOS 电路的晶体管级电路图,实现 YA*BC(DE).&#xff1f; 画出 YABC 的 CMOS 电路图&#xff0c;画出 YABCD 的 CMOS 电路图。 利用与非门和或非门实现 YABC(DE)((AB’)(CD)’(CE)’)’ 三个两输入与非门&a…