linux - 为什么不能使用 cat 逐行读取文件,其中每行都有分隔符

标签 linux bash for-loop cat

我有一个包含如下内容的文本文件:

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 手册中查找或循环也没有得到任何答案(http://www.gnu.org/software/bash/manual/bashref.html)。预先感谢您的帮助。

最佳答案

问题不在 cat 中,也不在 for 循环本身;它是在使用反引号。当你写:

for i in `cat file`

或(更好):

for i in $(cat file)

或(在 bash 中):

for i in $(<file)

shell 执行命令并将输出捕获为字符串,在 $IFS 中的字符处分隔单词。如果你想将行输入到 $i,你要么必须摆弄 IFS,要么使用 while 循环。 while 如果处理的文件有很大的危险,则循环更好;与使用 $(...) 的版本不同,它不必一次性将整个文件读入内存。

IFS='
'
for i in $(<file)
do echo "$i"
done

"$i" 周围的引号通常是个好主意。在这种情况下,修改后的$IFS,其实并不重要,但好习惯就是好习惯。它在以下脚本中很重要:

old="$IFS"
IFS='
'
for i in $(<file)
do
   (
   IFS="$old"
   echo "$i"
   )
done

当数据文件在单词之间包含多个空格时:

$ cat file
abc                  123,         comma
the   quick   brown   fox
jumped   over   the   lazy   dog
comma,   comma
$ 

输出:

$ sh bq.sh
abc                  123,         comma
the   quick   brown   fox
jumped   over   the   lazy   dog
comma,   comma
$

没有双引号:

$ cat bq.sh
old="$IFS"
IFS='
'
for i in $(<file)
do
   (
   IFS="$old"
   echo $i
   )
done
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$

关于linux - 为什么不能使用 cat 逐行读取文件,其中每行都有分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17099860/

相关文章:

swift - 如何反复更新 UILabel 并控制其变化速度?

Android ADB Linux 问题

ruby-on-rails - 从 Rails 应用程序中重新加载 nginx 配置

linux - 如何动态输出替换了一些字节的文件内容?

python - "Escaping"$ 从 python fabric 执行远程 bash 命令时

bash - 仅当重定向到管道或文件时,awk 没有输出

javascript - 通过过滤连接两个数组

linux - 我们可以检测 Xen 中 guest 操作系统的内存访问吗?

bash - 扩展 grep find 并复制到大文件夹(xargs?)

javascript - Node.js 泄漏 for..in 循环