0
点赞
收藏
分享

微信扫一扫

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

静悠 2022-09-16 阅读 70


第1部分 重新认识C语言

shell脚本中的文件操作


【文章摘要】

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

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

【关键词】

       shell  文件操作  读写  效率

 

一、概述

1000万行级,这就涉及到对程序执行方法和效率等的考虑。

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

 

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

1所示。

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

图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) 测试文件内容行数

zhou@linux:~/zhouzx/sh> wc -l Test1 Test2

122880 Test1

  4995 Test2

127875 total

 

       (2) 脚本执行结果

zhou@linux:~/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) 脚本执行结果

zhou@linux:~/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所示。

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

图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​​欢迎关注!)

举报

相关推荐

0 条评论