假设您有此文件:
$ 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 </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'
(如果在IFS=read-r p;do printf“%s\n”“'$p'”;done</tmp/test.txt时执行,则保留前导空格和尾随空格,但如果最后一行未以CR结尾,则仍会丢失)
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 </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'
如果您想去掉前导空格和交易空格,请删除IFS=部分:
$ while read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </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'
(一个没有终止符的文本文件,虽然在POSIX下很常见,但被认为是已损坏的。如果您可以指望结尾符,则在while循环中不需要||[[-n$line]]。)
更多关于BASH常见问题解答