我有一个包含以下内容的a.txt
文件
aaa
bbb
当我执行以下脚本时:
while read line
do
echo $line
done < a.txt > b.txt
生成的b.txt
包含以下内容
aaa
bbb
可以看到,行的前导空格已被删除。如何保留前导空格?
发布于 2015-04-17 10:26:43
在reading data line-by-line上的Bash FAQ条目中介绍了这一点。
read命令修改读取的每一行;默认情况下,它删除所有前导和尾随空格字符(空格和制表符,或IFS中存在的任何空格字符)。如果这不是期望的,则必须清除IFS变量:精确行,在IFS=读取-r行时不进行修剪;do printf '%s\n‘"$line“done < "$file"
正如Charles Duffy正确地指出的那样(我因为关注IFS
问题而错过了这一点);如果您想查看输出中的空格,那么在使用它时还需要对变量进行引号,否则shell将再次删除空格。
关于引用的代码片段中与原始代码相比的一些其他差异的注释。
在前面链接的页面顶部的一句话中介绍了read
的-r
参数的使用。
的-r选项可防止反斜杠解释(通常用作反斜杠换行符对,以便在多行中继续)。如果没有此选项,输入中的任何反斜杠都将被丢弃。您几乎应该始终对read使用-r选项。
至于使用printf
而不是echo
,不幸的是,echo
的行为并不是在所有环境中都是可移植的一致的,而且差异可能很难处理。另一方面,printf
是一致的,可以完全健壮地使用。
发布于 2015-04-17 10:25:47
这里有几个问题:
除非清除了whitespace.
echo $line
,否则read
会剥离前导和尾随的
$line
的内容,将其拆分为单独的单词,并将这些单词作为单独的参数传递给echo
命令。因此,即使在read
时清除了IFS,echo $line
仍然会丢弃前导空格和尾随空格,并将单词之间的空格序列分别更改为一个空格字符。此外,只包含字符*
的行将扩展为包含回显列表,这是一个重大改进,但仍然不能正确处理-n
等值,因为它本身将其视为回显参数。printf '%s\n' "$line"
将在不使用-r
的情况下修复此fully.
read
。将反斜杠视为连续字符,而不是文字内容,这样它们将不会包含在生成的值中,除非将其加倍以进行转义。因此:
while IFS= read -r line; do
printf '%s\n' "$line"
done
https://stackoverflow.com/questions/29689172
复制相似问题