让你提前认识软件开发(22):shell脚本中的文件操作

第1部分 重新认识C语言

shell脚本中的文件操作

【文章摘要】

编写shell脚本时,经常会涉及到对文件的操作,比如从文件中读取一行数据、向文件追加一行数据等。完成文件读写操作的方法有很多,了解各种命令下文件操作的执行情况,有助于开发人员在不同使用场景下选择合适的命令。

本文以实际的shell脚本为例,介绍了对文件进行操作的不同方法,为相关开发工作提供了参考。

【关键词】

shell  文件操作  读写  效率

一、概述

在某些软件项目的需求文档中,要求程序一次性读或写的数据规模较大,可达1000万行级,这就涉及到对程序执行方法和效率等的考虑。

本文比较了不同shell命令在对文件进行读或写操作过程中执行效率的不同,为大数据下文件操作命令的选择提供了参考。

二、文件比较算法流程介绍

文件比较算法的流程如图1所示。

图1 文件比较算法的流程

三、不同的文件内容读取命令

1. sed逐行读取数据

该命令在一个循环里,依次读取文件的每一行内容。

(1) 读取方法

举例:读取f1文件的第一行:sed –n 1p f1

读取f1文件的第二行:sed –n 2p f1

该命令实现简单,逻辑清晰。

         (2) 性能问题

如果用该命令进行大数据量(在十万数量级以上)的读取,发现程序执行效率低下,耗时较多(具体参见第3小节中的原因分析)。

2. 运用exec及read读取文件内容

(1) 打开读文件句柄

exec 3<testfile

其中,3是文件描述符(文件句柄),在linux取大于等于3的值(在aix下只能为[3,9]之间的值),该文描述符后续用来读取一行数据和关闭文件;testfile是要打开的文件。

(2) 读取一行数据

read str<&3

其中,3表示从该文件描述符读取数据;str是变量,用于保存从文件中读取的行数据。

(3) 关闭文件句柄

exec 3<&-

3. sed、exec及read读取文件内容测试脚本及效率比较

测试用exec及read方式逐行读取完一个122880行的文件,而用sed方式逐行读取完一个4995行的数据,测试脚本(命名为Test1.sh)如下:

#!/bin/sh

file="Test1"

file_row_count=`wc -l ${file} | awk ‘{print $1}‘`

date

exec 3<${file}

i=0

while [ $i -lt $file_row_count ]

do

read s1<&3

i=$((${i}+1))

done

exec 3<&-

################################################

file="Test2"

file_row_count=`wc -l ${file} | awk ‘{print $1}‘`

date

i=1

while [ $i -le $file_row_count ]

do

s1=`sed -n "${i}p" "${file}"`

i=$((${i}+1))

done

date;

测试结果如下:

(1) 测试文件内容行数

[email protected]:~/zhouzx/sh> wc -l Test1 Test2

122880 Test1

4995 Test2

127875 total

(2) 脚本执行结果

[email protected]:~/zhouzx/sh> ./Test1.sh

Wed May 14 15:18:56 CST 2014

Wed May 14 15:18:59 CST 2014

Wed May 14 15:19:12 CST 2014

从执行结果可以看出,用exec及read方式逐行读取完一个122880行的文件耗时3秒,而sed方式逐行读取完一个4995行的数据需要13秒。可见,运用exec及read后的文件读取效率有大幅的提升。

(3) sed命令在大数据量(在十万数量级以上)下读取效率低下原因分析

经分析,问题原因是sed命令读取一行数据太耗时。

sed读取一行数据有两个耗时的地方:

1) 每读取一行都会打开和关闭文件句柄,频繁的打开和关闭文件句柄成本高昂。

2) sed读取某一行时有一个定位的过程,比如想要读取第10万行,则该命令执行时首先需要从头开始查找一直定位到第10万行,此种执行方式的成本也很高,并且随着数据行数的增加成本不断地增加。

上面的两个耗时的地方在只执行一次sed命令读取一行数据时并不明显,但将该命令放在一个100万级的循环内,其效率问题就显得非常突出了。

四、不同的写文件方式

主要有两种方式。

1. 运用>>向文件追加一行数据

这是常用的操作方式。

2. 运用exec方式向文件追加数据

(1) 打开写文件句柄

exec 3>testfile

3是文件描述符(文件句柄),在linux下取大于等于3的值(在aix下只能为[3,9]之间的值),该文描述符后续用来读取一行数据和关闭文件;testfile是要打开的文件。

(2) 写入一行数据

echo “${str}”>&3

3表示从该文件描述符读取数据;str是变量,表示向文件描述符写入的行数据。

(3) 关闭写文件句柄

exec 3>&-

3. 写文件内容测试脚本及效率比较

测试用>>方式向文件追加100万行数据,同时用exec方式向文件追加100万行数据,测试脚本(命名为Test2.sh)如下:

#!/bin/sh

str="Hello, world!"

cnt=1000000

date;

file="test3"

>${file}

i=0

while [ $i -lt $cnt ]

do

echo "${str}">>${file}

i=$((${i}+1))

done

date;

###################################

file="test4"

>${file}

exec 3>${file}

i=0

while [ $i -lt $cnt ]

do

echo "${str}">&3

i=$((${i}+1))

done

exec 3>&-

date;

测试结果如下:

(1) 脚本执行结果

[email protected]:~/zhouzx/sh> ./Test2.sh

Wed May 14 15:12:47 CST 2014

Wed May 14 15:13:27 CST 2014

Wed May 14 15:14:03 CST 2014

(2) 生成文件内容

生成文件test3和test4中的内容完全相同,test3(或test4)文件部分截图如图2所示。

图2 test3文件部分截图

从执行结果可以看出,用>>方式向文件追加100万行数据耗时40秒,而用exec方式向文件追加100万行数据耗时36秒。用exec方式节约下来的4秒时间是非常可观的,在大数据量下可进一步提升了程序执行效率。

五、总结

提升程序执行效率是程序设计中一个永恒的话题,作为优秀的软件开发工程师,一定要学会在已有程序的基础之上对算法进行优化,以提升程序及软件产品的运行效率。

本文比较了不同shell命令在对文件进行读或写操作过程中执行效率的不同,并用脚本演示了不同命令执行时间的差距。通过对本文的阅读,希望大家能够对shell环境下文件操作有更为深刻的认识。

(欢迎访问南邮BBS:http://bbs.njupt.edu.cn/)
(欢迎访问重邮BBS:http://bbs.cqupt.edu.cn/nForum/index)

(本系列文章每周更新两篇,敬请期待!本人微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)

让你提前认识软件开发(22):shell脚本中的文件操作

时间: 2024-08-03 23:20:31

让你提前认识软件开发(22):shell脚本中的文件操作的相关文章

让你提前认识软件开发(23):如何在C语言中执行shell命令?

第1部分 重新认识C语言 如何在C语言中执行shell命令? [文章摘要] Linux操作系统具备开源等诸多优秀特性,因此在许多通信类软件(主流开发语言为C语言)中,开发平台都迁移到了Linux上,同时shell操作在Linux的编程中占有很重要的地位,这就需要开发人员熟练掌握在C语言中执行shell命令的相关操作. 本文用实际的代码演示了如何在C语言程序中执行shell命令,为相关软件开发工作的开展提供了参考. [关键词] Linux  C语言  shell  命令  开发 一.程序执行流程

让你提前认识软件开发(46):首先是为人编写程序,其次才是计算机

第3部分 软件研发工作总结 首先是为人编写程序,其次才是计算机 "首先是为人编写程序,其次才是计算机",这是软件开发的基本要点,软件的生命周期贯穿于产品的开发.测试.生产.发布.用户使用.版本升级和后期维护等长期过程中,只有易读.易维护的软件代码才具有生命力. 在实际的软件开发过程中,可能是由于工作很忙的原因,很多开发人员只注重实现程序的基本功能,而忘记了编程规范,因此写出来的代码只能让计算机看懂,人要看懂很不容易.更有甚者,有些项目组为了赶进度,明确要求组员以实现产品功能为主,代码能

让你提前认识软件开发(45):代码的第一印象

第3部分 软件研发工作总结 代码的第一印象 我们都很注重给别人的第一印象,也有很多书籍教我们怎样给别人留下一个美好印象的.确实,如果我们第一眼看到某个人,就觉得很不爽,那么一定会在心理上产生抵触,以后再见到他,会有一种疏远的感觉.也正因为如此,当今社会交往中的"面子工程"很重要,不管怎样,先撑足了自己的脸面再说. 代码也一样,也会给别人留下或好或差的印象.当我们看到优美的代码时,会有一种想继续研究下去的欲望,甚至会有一种觉得很享受的感觉.相反,当我们看到丑陋的代码时,就会咬牙切齿,因为

让你提前认识软件开发(44):如何解决软件故障?

第3部分 软件研发工作总结 如何解决软件故障? 在软件产品的运营维护阶段,软件工程师的一项重要工作就是解决软件的bug.在学校的时候,大家学完一门课程,然后考试通过就万事大吉了.但在实际的软件开发项目中,将软件成功交付给客户,只是"万里长征走完了第一步",后面还有大量的工作要做,例如:解决软件故障.新增功能.版本升级等.作为一名合格的软件工程师,一定要学会准确.迅速地解决软件出现的各种问题. 为什么解决软件问题的能力如此重要?因为软件项目的成功率不容乐观.国内某IT公司对本公司内软件项

让你提前认识软件开发(40):既要写好代码,又要写好文档

第3部分 软件研发工作总结 既要写好代码,又要写好文档 对于软件相关行业,在学校或单位上,大家也许都已经注意到了,除了要编写的程序.绘制设计图之外,还有一个重要的工作便是写文档.为什么要写文档呢?因为我们要把自己做的东西展示出来,不光展示给同行看,可能还要展示给其他岗位上的工作人员看,甚至展示给用户看.如果我们只是会写程序,不会在文档中描述自己的想法,那么就真正的成为"码农"了. 工作也有一段时间了,我发现周围的同事,会写高质量文档的确实很少.李开复老师在<浪潮之巅>的序言

让你提前认识软件开发(20):如何在C语言里面执行SQL语句?

[文章摘要] 在通信类软件中,程序经常需要与数据库打交道.为了实现诸如从数据库中获取数据.更新数据库表某字段.插入或删除某条数据等功能,就需要在C语言程序中构造一些SQL语句,并用函数来执行这些SQL语句. 本文介绍如何在C语言程序中构造并执行SQL语句,为相关软件开发工作的开展提供了参考. [关键词] SQL语句  C语言  程序  流程  开发 一.为什么要在C语言程序中执行SQL语句? 在C语言程序中执行SQL语句的原因有以下几个: (1) 程序需要获取数据库中某数据表的字段值,并对这些字

让你提前认识软件开发(47):同行评审

第3部分 软件研发工作总结 同行评审 在<浪潮之巅>这本书中,吴军老师描述了在Google早期的工作方式,其中有一段是这么写的:我一般会在吃完晚饭后把代码修改的清单发给克雷格做代码审核,他一般晚上10点左右会回复我,给我修改意见,详细到某一行多了一个空格. 吴军老师所描述的内容,其实就是软件开发中的同行评审流程. 几乎在所有的软件项目中,都需要同行评审.一个人不管能力多强,看问题的角度总会受到限制,写出来的程序和文档等定不会是十全十美的.如果能够让懂行的同事给参阅一下,并提出他们认为正确的意见

让你提前认识软件开发(28):数据库存储过程中的重要表信息的保存及相关建议

第2部分 数据库SQL语言 数据库存储过程中的重要表信息的保存及相关建议 1. 存储过程中的重要表信息的保存 在很多存储过程中,会涉及到对表数据的更新.插入或删除等,为了防止修改之后的表数据出现问题,同时方便追踪问题,一般会为一些重要的表建立一个对应的debug表.这个debug表中的字段要包括原表的所有字段,同时要增加操作时间.操作码和操作描述等字段信息. 例如,在某项目中,包括了如下一个重要的表tb_XXX: create table tb_XXX (      AAA           

让你提前认识软件开发(24):C语言的发展历史和主要特点

第1部分 重新认识C语言 C语言的发展历史和主要特点 作为一门众所周知的计算机编程语言,C语言是谁发明的呢?它是如何演进的?它有何特点?到底有多少人在使用它? 1. C语言之父 C语言是1972年由美国贝尔实验室的计算机科学家Dennis Ritchie(丹尼斯·里奇)设计发明的.因此,Dennis Ritchie被誉为"C语言之父"(他已于2011年10月9日去世,享年70岁).图1中的人物就是Dennis Ritchie. 图1 "C语言之父" Dennis R