我有a.txt以下内容的文件
aaa
bbb
Run Code Online (Sandbox Code Playgroud)
当我执行以下脚本时:
while read line
do
echo $line
done < a.txt > b.txt
Run Code Online (Sandbox Code Playgroud)
生成b.txt包含以下内容
aaa
bbb
Run Code Online (Sandbox Code Playgroud)
可以看出,线条的前导空间已被删除.我怎样才能保留领先的空间?
Eta*_*ner 40
关于逐行读取数据的Bash FAQ条目对此进行了介绍.
read命令修改每行读取; 默认情况下,它会删除所有前导和尾随空白字符(空格和制表符,或IFS中存在的任何空格字符).如果不需要,则必须清除IFS变量:
Run Code Online (Sandbox Code Playgroud)# Exact lines, no trimming while IFS= read -r line; do printf '%s\n' "$line" done < "$file"
正如查尔斯达菲正确地指出的那样(并且我因为关注这个IFS问题而错过了); 如果你想在输出中看到空格,你还需要在使用它时引用变量,否则shell将再次删除空格.
关于引用代码段与原始代码相比的其他一些差异的注释.
-r参数的使用read包含在先前链接页面顶部的单个句子中.
读取的-r选项可防止反斜杠解释(通常用作反斜杠换行符对,以继续多行).如果没有此选项,输入中的任何反斜杠都将被丢弃.您应该几乎总是将-r选项与read一起使用.
至于使用printf而不是echo那里的行为echo,有点不幸的是,在所有环境中并不是可移植的,并且差异可能很难处理.printf另一方面,它是一致的,可以完全稳健地使用.
Cha*_*ffy 14
这里有几个问题:
IFS被清除,否则read剥离前导和尾随空格.echo $linestring-splits和glob-expands的内容$line,将其分解为单个单词,并将这些单词作为单独的参数传递给echo命令.因此,即使IFS在read时间被清除,echo $line仍然会丢弃前导和尾随空格,并将单词之间的空格更改为单个空格字符.此外,仅包含该字符的*行将被展开以包含文件名列表.echo "$line"是一个重大的改进,但仍然不能正确处理诸如-n它本身作为echo参数的值.printf '%s\n' "$line"会完全解决这个问题.read不-r将反斜杠视为连续字符而不是文字内容,这样它们就不会包含在生成的值中,除非加倍自行转义.从而:
while IFS= read -r line; do
printf '%s\n' "$line"
done
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12973 次 |
| 最近记录: |