【linux shell】while read line几种方法以及区别


引言:开始时自己的写的一个下载某个bing网站上面的图片的脚本程序中需要使用while read line读取自己提取出来的图片信息,刚开始没有用临时文件存放信息,而是直接使用管道机制重定向,结果……坑了我一个小时
==然后自己查了一些资料,比较一下三种while read line方法的区别==
首先自己的test文件如下:(就简单是三行数据)
test文件内容

while-read-line三种方法

1. 形如cat test | while read line;do echo $line;done

  • 代码如下
    name1="xiaowang"
    date1="2020-05-08"
    cat test | while read date
    do
        read url
        read name
        name1="$name"
        date1="$date"
        echo "$date1 $name1 $url"
        echo "$date $name $url"
    done
    
    echo "888888 $date1 777 $name1 666  $url"
  • 结果输出
    2020-05-07 https://bing.ioliu.cn/photo/WildflowerWeek_ZH-CN4593499387?force=download 印克斯湖国家公园中的德克萨斯矢车菊,德克萨斯州
    2020-05-07 https://bing.ioliu.cn/photo/WildflowerWeek_ZH-CN4593499387?force=download 印克斯湖国家公园中的德克萨斯矢车菊,德克萨斯州
    888888 2020-05-08 777 xiaowang 666

我想的是使用while read line读取文件之后赋值给name1和date1,结果并没赋值。刚开始很疑惑,明明在while循环中的name1和date1都赋值了为啥退出之后没了呢,结果发现是管道的机制,这个使用管道之后while read line是在子shell中进行的,所以在退出while之后其中的操作都是无效的

另外,参考一片博客中说的:cat test会一次性将test文件所有数据装入内存,如果test文件足够大,会直接占用巨量内存

2.形如 while read line <test;do echo $line;done

  • 代码如下

    name1="xiaowang"
    date1="2020-05-08"
    while read date < test
    do
        read url
        read name
        name1="$name"
        date1="$date"
        echo "$date1 $name1 $url"
        echo "$date $name $url"
    done
    
    echo "888888 $date1 777 $name1 666  $url"
  • 结果如下

       
    
    2020-05-07  
    2020-05-07  
    
    
    2020-05-07  
    2020-05-07  
    
    
    2020-05-07  
    2020-05-07  
    ...

首先我看不懂这个输出结果(其中的空行全是我自己按的回车,也就是按了两次回车之后才出现结果,然后这个while循环一直不结束…)查说法就是:它会在每次循环的时候都重新打开test文件,使得每次都从头开始读数据,而不是每次从上一次标记的地方继续读数据。

3.【最佳】形如while read line;do echo $line;done <test

  • 代码如下

    name1="xiaowang"
    date1="2020-05-08"
    while read date
    do
        read url
        read name
        name1="$name"
        date1="$date"
        echo "$date1 $name1 $url"
        echo "$date $name $url"
    done < test
    
    echo "888888 $date1 777 $name1 666  $url"
  • 结果如下(正常了耶)

    2020-05-07 https://bing.ioliu.cn/photo/WildflowerWeek_ZH-CN4593499387?force=download 印克斯湖国家公园中的德克萨斯矢车菊,德克萨斯州
    2020-05-07 https://bing.ioliu.cn/photo/WildflowerWeek_ZH-CN4593499387?force=download 印克斯湖国家公园中的德克萨斯矢车菊,德克萨斯州
    888888 2020-05-07 777 https://bing.ioliu.cn/photo/WildflowerWeek_ZH-CN4593499387?force=download 666  印克斯湖国家公园中的德克萨斯矢车菊,德克萨斯州

这个不就是我想要的结果吗,使用输入重定向的方式则每次只占用一行数据的内存,而且是在当前shell环境下执行的,while内的变量赋值、数组赋值在退出while后仍然有效。

总结

  1. 以上三种方法中,大家在选取的时候最好选择第三那种方法,别问为什么问。
  2. 其实读取文件内容的方法有很多,比如使用形如:for line in $(<file); do echo ​$line; done的方法,据说这种方法效率最高,具体可以参考这篇博客,这个说了几种while read和for的比较。
  3. 另外如果想要了解我那个下载图片的脚本程序可以访问我的github

参考

https://www.cnblogs.com/xl-892694298/p/11017168.html
https://blog.csdn.net/u014650722/article/details/51563823


文章作者: PengShuai
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 PengShuai !
评论
  目录