我有一个文本文件,其中包含这样的内容:
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
我写了个剧本
for i in `cat file`
do
echo $i
done
由于某种原因,脚本的输出不是逐行输出文件,而是在逗号和换行符处将其断开。为什么cat或“for blah in cat xyz
“会这样做?如何使其不这样做?我知道我可以使用
while read line
do
blah balh blah
done < file
但是我想知道为什么cat或“for blah in”这样做来加深我对unix命令的理解。Cat的手册页没有帮助我,在bash手册中查找for或循环也没有得到任何答案(http://www.gnu.org/software/bash/manual/bashref.html)。提前感谢您的帮助。
6条答案
按热度按时间798qvoo81#
问题不在
cat
,也不在for
循环本身;关键在于反引号的使用。当你这样写的时候:或(更好):
或(单位:
bash
):shell执行命令并将输出捕获为字符串,以
$IFS
中的字符分隔单词。如果您希望将行输入到$i
,则必须修改IFS
或使用while
循环。如果存在处理的文件过大的危险,则while
循环更好;它不必一次将整个文件读入内存,这与使用$(...)
的版本不同。"$i"
的引号通常是一个好主意。在这个上下文中,对于修改后的$IFS
,引号实际上并不重要,但即使如此,好习惯仍然是好习惯。在下面的脚本中,引号很重要:当数据文件在单词之间包含多个空格时:
输出:
不带双引号:
bzzcjhmw2#
u0njafvf3#
您可以使用
IFS
变量来指定您想要一个换行符作为字段分隔符:jjjwad0x4#
for循环加上内部字段分隔符(IFS)的更改将按预期读取文件
对于输入
与IFS更改耦合的For循环
导致
bybem2ql5#
IFS -内部字段分隔符可以设置为得到你想要的。
要一次读取整行,请用途:IFS="”
13z8s7eq6#
为了防止新的
IFS
设置改变你的shell,你不需要做任何其他提到的事情...通过将命令放在圆括号中来使用子shell(我也更喜欢使用转义序列来设置IFS;这使得更容易阅读所做的事情):
分号代替了必要的换行符,圆括号打开了一个subshell,
$(...)
语法用输出到stdout代替了subshell调用,单引号前的$
导致了单引号内的转义序列解释(不适用于双引号,是一种bashism,即不适用于任何其他POSIX shell)。或者,您可以
或者甚至可以将
do
或圆括号放在它们自己的行上,如果这是您想要的。