Bash读取短文本文件到变量时丢失末尾空行
解决文件末尾空行读取到变量丢失的问题
这个问题我之前也碰到过!根源在于shell的命令替换($(...))会自动剥离输出末尾的所有换行符,所以当文件最后是一个空行(本质就是一个换行符)时,命令替换后这行就丢失了。给你几个可行的解决办法:
方法1:使用read命令读取整个文件
read命令加上-d ''选项可以将分隔符设为空,从而读取整个文件直到EOF,同时保留所有换行符。配合IFS=和-r选项还能避免意外修改文件内容:
rm -f /tmp/a ; for i in $(seq 3) ; do echo $i >> /tmp/a; done; echo >> /tmp/a; cat /tmp/a; echo "---"; IFS= read -r -d '' var < /tmp/a; echo "$var"
IFS=:防止开头的空格/制表符被自动截断-r:禁止反斜杠转义,保留文件原始内容-d '':将终止符设为空,让read读取到文件结束
方法2:通过追加标记字符再移除的方式
先在文件内容末尾追加一个不会出现在文件中的标记字符,完成命令替换后再移除这个标记,这样就能保留原本的末尾换行:
rm -f /tmp/a ; for i in $(seq 3) ; do echo $i >> /tmp/a; done; echo >> /tmp/a; cat /tmp/a; echo "---"; var=$(cat /tmp/a; echo -n 'MARKER'); var=${var%'MARKER'}; echo "$var"
这个方法兼容性更好,适合所有POSIX兼容的shell,不用担心read命令的版本限制。
为什么原方法会丢失空行?
当你用var=$(cat /tmp/a)时,shell会执行cat命令,然后把它的输出去掉所有末尾的换行符,再赋值给变量。文件最后的空行就是一个单独的换行符,自然会被剥离掉。上面的两种方法都是绕开这个机制,完整保留文件的所有内容。
内容的提问来源于stack exchange,提问作者Paavo Leinonen
相关产品推荐
相关产品推荐

