假设你有这个文件:
$ cat /tmp/test.txt
Line 1
Line 2 has leading space
Line 3 followed by blank line
Line 5 (follows a blank line) and has trailing space
Line 6 has no ending CR
有四个元素会改变许多Bash解决方案读取的文件输出的含义:
空行4;
两行上的前导或尾随空格;
维护各行的含义(即每行是一条记录);
第6行未以CR终止 .
如果希望逐行包含文本文件(包括空行和没有CR的终止行),则必须使用while循环,并且必须对最后一行进行备用测试 .
以下是可能更改文件的方法(与 cat 返回的内容相比):
1)丢失最后一行以及前导和尾随空格:
$ while read -r p; do printf "%s\n" "'$p'"; done
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
(如果改为 while IFS= read -r p; do printf "%s\n" "'$p'"; done
2)使用 cat 进程替换将一次读取整个文件并且失去了各行的含义:
$ for p in "$(cat /tmp/test.txt)"; do printf "%s\n" "'$p'"; done
'Line 1
Line 2 has leading space
Line 3 followed by blank line
Line 5 (follows a blank line) and has trailing space
Line 6 has no ending CR'
(如果从 $(cat /tmp/test.txt) 中删除 " ,则逐字而不是一次读取文件 . 也可能不是预期的...)
逐行读取文件并保留所有间距的最强大和最简单的方法是:
$ while IFS= read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done
'Line 1'
' Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space '
'Line 6 has no ending CR'
如果您想剥离领先和交易空间,请删除 IFS= 部分:
$ while read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
'Line 6 has no ending CR'
(没有终止 \n 的文本文件虽然相当常见,但在POSIX下被视为已损坏 . 如果您可以指望尾随 \n ,则 while 循环中不需要 || [[ -n $line ]] . )