热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《UNIX编程环境》——5.9get和put:追踪文件变动

本节书摘来自异步社区《UNIX编程环境》一书中的第5章,第5.9节,作者:【美】BrianW.Kernighan,RobPike著

本节书摘来自异步社区《UNIX编程环境》一书中的第5章,第5.9节,作者:【美】Brian W. Kernighan , Rob Pike著,更多章节内容可以访问云栖社区“异步社区”公众号查看

5.9 get和put:追踪文件变动

这一节是本章的最后一节,我们将介绍一个更大、更复杂的例子,以此说明shell如何与awk和sed进行合作。

程序在开发过程中不断地改正错误和增加新功能。版本追踪往往是不可少的。特别是有的用户把程序移植到其他的机器上使用—他们常常跑回来问“在我们的版本之后又有哪些改动”,或者“这个那个错误是怎么改的”。保留备份使尝试新思想也变得更加安全稳妥:如果新的程序不成功,利用备份很容易回到原来的程序。

保存所有版本是一种备份方法。然而这样做不易组织,同时占用磁盘空间太多。我们可以利用一个可能性,即相邻两版本间通常大部分是重复不变的,从而只要保存一次即可。用diff -e命令生成一个ed命令列表,可以把老版本转换成新版本:

screenshot

这样,通过维护一个完整的版本,以及把这个版本转换为任何其他版本的一组编辑命令,就可以把文件的所有版本都保留在一个(不同的)文件中。

这种方法有两种组织方式:一种是保留最新的完整版本和转换到老版本的编辑命令,另一种是保留最老的版本和转换到新版本的编辑命令。虽然后一种方式比较容易实现,但是当有很多版本时,前一种方式使用较快,因为我们一般总是对当前版本感兴趣。

我们选择第一种组织方式。在一个我们称之为“历史文件”的文件中,保存当前版本和多组编辑命令,每组编辑命令把某一版本转换为前一版本。各组编辑命令以下一行信息开始:

screenshot

摘要为单行,由个人提供,它描述文件的改动。

有两个维护版本的命令:get和put。get命令从历史文件里获得版本,put命令在得到一个单行的变动摘要后,把一个新的版本放入历史文件中。

在介绍具体实现之前,我们先举例说明get和put如何工作,以及历史文件是怎样维护的:

screenshot

其中“编辑命令”是由2d行命令组成的,表示删除文件的第2行,这样就可以将新版本转换为老版本。

screenshot

编辑命令从上到下编辑历史文件,用来产生所要求的版本:第一组编辑命令把最新的版本转换为次新的版本,下一组命令把次新的版本换成第三新的版本,依此类推。因此,实际上每调用一次ed命令就把文件向老版本推进了一个版本。

如果被修改的文件包含行首为@@@的行,会引起一些麻烦,另外diff(1)命令的BUGS段将对只含一个句号的行给出警告。我们选择@@@作为编辑命令的标题头记号,因为标准正文一般不会用到这种序列。

讨论get和put命令的使用说明和命令的各种不同形式需要很多篇幅,所以我们只给出它们最后的形式。put命令比较简单,其程序为:

screenshot

读完一行摘要之后,put调用get从历史文件中提取前一个版本。get的-o选项表示给出一个不同的输出文件名。如果get找不到历史文件,它返回一个错误状态,而put将创建一个新的历史文件。如果历史文件已经存在,then子句以临时文件的形式创建一个新的历史文件,文件创建依次利用下列内容:最新版本,@@@行,新版本转换为次新版本的编辑命令,以及老的编辑命令和@@@行。最后,用overwrite把临时文件复制到历史文件。

get程序比put程序更复杂,主要是因为有一些选项:

screenshot

这些选项很普通。-i和-o指定输入和输出文件名。-[0-9]选择特定的版本:0表示最新版本(默认值),-1表示次新版本,依次类推。循环while语句,用test和shift实现对全部参数的遍历。循环不用for语句,因为某些选择项(-i、-o)要使用其他参数,所以要用shift把对应参数移出,而位于for循环语句内部的shift语句不能与for很好的合作。ed的“-”选项关闭了在读写文件时通常使用的符号计数功能。

程序

screenshot

(这是我们在put中使用的形式)但是更紧凑,对于熟悉操作符¦¦ 的程序员来说也更清楚。{和}之间的命令表示在当前shell下执行,而不是在子shell下执行;这样就保证了exit是从get退出,而不从子shell退出。字符{和}很像do和done—它们只在分号、换行或命令终止符之后才具有特殊作用。

最后,我们介绍get程序的工作代码。首先,sed把历史文件分成两部分:最新版本和编辑命令集合。然后由awk程序处理编辑命令。最后对@@@行进行计数(但不打印),同时传递编辑命令,直到计数值超过所期望的版本数(回忆一下,awk命令的默认动作是打印输入行)。两个ed命令$d和w附加在历史文件中的命令后:$d删除sed留在当前版本里的@@@行,而w命令完成文件的最后写入。这里不需要overwrite,因为get程序只改变文件的版本,而不改变先前的历史文件。

练习5-29 编写一个命令version,完成下述两件工作:

screenshot

报告摘要,修改日期和修改人,对历史文件中选定版本进行修改。

screenshot

报告9月20日的版本号。这被典型地用于下面命令中(version可以方便地回送历史文件名):

screenshot

练习5-30 修改get和put,使之可以操作其他目录下的历史文件,不至于因为.H文件把工作目录弄乱。

练习5-31 一旦工作完成,不再需要保留所有的文件版本。怎样实现从历史文件中删除一些版本呢?



推荐阅读
  • 文章目录一、awk简介二、awk的两种形式语法格式1options:2command:三、awk工作原理四、记录与字段相关内部变量:五、格式化输出:printf函数六、awk模式和 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
  • UNIX高级环境编程 第11、12章 线程及其属性
    第11章线程11.2线程概念线程资源:线程ID,一组寄存器,栈,调度优先级和策略,信号屏蔽字,e ... [详细]
  • 【技术分享】一个 ELF 蠕虫分析
    【技术分享】一个 ELF 蠕虫分析 ... [详细]
  • 201720181 20155339 《信息安全系统设计基础》第六周学习总结
    2017-2018-120155339《信息安全系统设计基础》第六周学习总结教材学习内容总结控制转移:从ak指令到a(k1)指令的过渡。控制转移序列称为处理器的控制流 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
author-avatar
MySeptember
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有