使用while read循环读取文件时,标准输入首行丢失原因探究
问题原因与解释
核心现象拆解
当你用while read x; do sed ''; done < file处理含1-5的文件时,只输出2、3、4、5;但换成while read x; do printf 'something\n'; done < file却能输出5行内容。本质差异在于循环体里的命令是否会读取共享的标准输入流。
根本原因
整个while循环的标准输入被重定向到了file,意味着read和循环体里的sed/awk/cat共用同一个输入流:
- 第一次循环时,
read x先从输入流中读取第一行(内容为1),此时文件的读取指针跳到了第二行开头。 - 接着执行
sed '',它会从当前指针位置开始,一次性读取输入流中剩下的所有内容(2到5)并输出,同时把指针移到文件末尾。 - 后续
read x再尝试读取时,输入流已经没有内容了,读取失败导致循环直接终止——所以实际循环只执行了1次,第一行1被read读走但没被输出,自然看不到。
而printf不会读取标准输入,每次循环里read x都能正常读取下一行,直到5行全部读完,因此循环执行5次。
解决方法
如果要逐行处理文件内容,别让循环体命令直接读共享的标准输入,而是把read读到的内容传递给它:
- 示例:
while read x; do echo "$x" | sed ''; done < file,这样会输出完整的1-5。 - 更高效的方式:直接用
sed/awk处理整个文件,比如sed '' file,不需要嵌套while循环。
内容的提问来源于stack exchange,提问作者Arshaluys Smbatyan
相关产品推荐
相关产品推荐

