Bash read忽略前导空格
我有一个包含以下内容的文件Bash read忽略前导空格,bash,Bash,我有一个包含以下内容的文件a.txt aaa bbb 当我执行以下脚本时: while read line do echo $line done < a.txt > b.txt 可以看出,行的前导空格已被删除。如何保留前导空格?这里有几个问题: 除非清除了IFS,否则read会去除前导和尾随空格 echo$line字符串拆分和glob展开$line的内容,将其拆分为单个单词,并将这些单词作为单个参数传递给echo命令。因此,即使在read时间清除了IFS
a.txt
aaa
bbb
当我执行以下脚本时:
while read line
do
echo $line
done < a.txt > b.txt
可以看出,行的前导空格已被删除。如何保留前导空格?这里有几个问题:
- 除非清除了
,否则IFS
会去除前导和尾随空格read
字符串拆分和glob展开echo$line
的内容,将其拆分为单个单词,并将这些单词作为单个参数传递给$line
命令。因此,即使在echo
时间清除了IFS,read
仍将丢弃前导和尾随空格,并将单词之间的空格更改为单个空格字符。此外,仅包含字符echo$line
的行将展开以包含文件名列表*
是一个显著的改进,但仍然无法正确处理echo“$line”
等值,它将这些值本身视为echo参数-n
将完全修复此问题printf“%s\n”“$line”
- 不带
的-r
将反斜杠视为连续字符而不是文字内容,因此,除非将反斜杠折叠以转义,否则它们不会包含在生成的值中read
这里有几个问题:
- 除非清除了
,否则IFS
会去除前导和尾随空格read
字符串拆分和glob展开echo$line
的内容,将其拆分为单个单词,并将这些单词作为单个参数传递给$line
命令。因此,即使在echo
时间清除了IFS,read
仍将丢弃前导和尾随空格,并将单词之间的空格更改为单个空格字符。此外,仅包含字符echo$line
的行将展开以包含文件名列表*
是一个显著的改进,但仍然无法正确处理echo“$line”
等值,它将这些值本身视为echo参数-n
将完全修复此问题printf“%s\n”“$line”
- 不带
的-r
将反斜杠视为连续字符而不是文字内容,因此,除非将反斜杠折叠以转义,否则它们不会包含在生成的值中read
上的Bash常见问题解答条目中介绍了这一点 read命令修改读取的每一行;默认情况下,它删除所有前导和尾随空格字符(空格和制表符,或IFS中存在的任何空格字符)。如果不需要,则必须清除IFS变量:
# Exact lines, no trimming
while IFS= read -r line; do
printf '%s\n' "$line"
done < "$file"
#线条精确,无需修剪
而IFS=读取-r行;做
printf'%s\n'$行
完成<“$file”
正如查尔斯·达菲(Charles Duffy)正确指出的那样(我没有注意到IFS
问题);如果希望在输出中看到空格,则在使用变量时还需要引用该变量,否则shell将再次删除空格
请注意,与原始代码相比,该引用代码段中的一些其他差异
在前面链接的页面顶部的一句话中介绍了如何使用-r
参数来读取
read的-r选项可防止反斜杠解释(通常用作反斜杠换行对,以在多行上继续)。如果没有此选项,输入中的任何反斜杠都将被丢弃。您几乎应该始终在read中使用-r选项
至于使用
printf
而不是echo
,有点遗憾的是,echo
的行为在所有环境中都是不可移植的一致性的,处理这些差异可能会很困难<另一方面,code>printf是一致的,可以完全可靠地使用。上的Bash常见问题解答条目介绍了这一点
read命令修改读取的每一行;默认情况下,它删除所有前导和尾随空格字符(空格和制表符,或IFS中存在的任何空格字符)。如果不需要,则必须清除IFS变量:
# Exact lines, no trimming
while IFS= read -r line; do
printf '%s\n' "$line"
done < "$file"
#线条精确,无需修剪
而IFS=读取-r行;做
printf'%s\n'$行
完成<“$file”
正如查尔斯·达菲(Charles Duffy)正确指出的那样(我没有注意到IFS
问题);如果希望在输出中看到空格,则在使用变量时还需要引用该变量,否则shell将再次删除空格
请注意,与原始代码相比,该引用代码段中的一些其他差异
在前面链接的页面顶部的一句话中介绍了如何使用-r
参数来读取
read的-r选项可防止反斜杠解释(通常用作反斜杠换行对,以在多行上继续)。如果没有此选项,输入中的任何反斜杠都将被丢弃。您几乎应该始终在read中使用-r选项
至于使用
printf
而不是echo
,有点遗憾的是,echo
的行为在所有环境中都是不可移植的一致性的,处理这些差异可能会很困难<另一方面,code>printf是一致的,可以完全可靠地使用。如果不提供用于保存输入的read
任何参数(取决于默认变量REPLY
),则不会删除空格,并且可以省略对IFS
的修改。也就是说,在read-r时,;不打印“%s\n”$REPLY;完成<“$file”
我不确定;据我所知,它似乎没有被记录在案。如果您认为它是零参数,需要将行拆分为零,那么它是有意义的
# Exact lines, no trimming
while IFS= read -r line; do
printf '%s\n' "$line"
done < "$file"