为什么“While ... do ... done”的循环无法读取文本文件?

时间:2014-03-04 12:52:52

标签: bash text-files

我想要做的工作是从文本文件中读取一行(当前这个文件只包含一行,后面会增加行数),循环为“While ... do ... done” 。奇怪的是它只能读取一些文本文件。我的代码是:

...(previous commands to create "myfile.txt")...
while read -r line
do
 echo "flag" 
done < "myfile.txt"

我试了几个案子。如果我用另一个在当前目录中手动创建的文件“test.txt”替换了“myfile.txt”(这个“test.txt”也包含一行),我的脚本可以打印“flag”。

同样,在创建“myfile.txt”之后,如果我修改并将其保存在当前目录中,然后运行我的脚本,它可以正常打印“flag”。

除上述两种情况外,我的脚本无法打印“标志”。 我也尝试在我的脚本中“chmod”和“触摸”文本文件,如下所示,它也无法工作。

显然,我希望我的脚本读取文本文件的行,有人可以告诉我原因并给出解决方案吗?

顺便说一句,这个文件可以通过cat命令读取。

...(previous commands to create "myfile.txt")...
chmod 777 "myfile.txt"
touch "myfile.txt"
cat "myfile.txt" #(I can see the results of this line)
while read -r line
do
 echo "flag" 
done < "myfile.txt"

谢谢!

创建文本文件的整个代码大约是800行。但是,我想发布创建我的文本文件的行。他们在这里:

  for(i = 1, i<=6, ++i){ 
    ...
    ofstream myfile("myfile.txt", std::ios_base::app);
     ...
    if(myfile.is_open()){
       myfile << "rms_" << std::setprecision(3) << RMS_values ;
       myfile.close();
    }
  }

****************我的解决方案开始*************************** *************

感谢您的上述回复。

我自己解决了这个链接:https://unix.stackexchange.com/questions/31807/what-does-the-noeol-indicator-at-the-bottom-of-a-vim-edit-session-mean

原因是在我的脚本中生成文本文件,最后没有“\ n”。因此,当在VI中打开文件名时,文本文件后面有一个“[noeol]”图标。

根据上面的链接,如果没有“[noeol]”,UNIX / LINUX将不会读取此文件。

解决方案相当简单(后面看),只需在“cout”结尾添加“&lt;&lt;”&n;“n”。该行变为,

 myfile << "rms_" << std::setprecision(3) << RMS_values << "\n";

****************我的解决方案结束*************************** *************

3 个答案:

答案 0 :(得分:1)

$ cat test.sh

#!/bnin/bash
echo "content" > "myfile.txt"
cat "myfile.txt" #(I can see the results of this line)
while read -r line
do
 echo "flag" 
done < "myfile.txt"

$ bash test.sh

content
flag

<强> $

有效。它没有问题。该脚本是您发布内容的精确副本,但触摸被某些内容替换,因为while循环在文件中每行打印一条消息,所以如果没有行(和{{1} }不会添加任何),显然不会打印任何内容。

答案 1 :(得分:1)

我在这里猜测:

在Unix中,有两个关于文本文件的假设:

  • 所有行以<LF>字符结尾。如果您在使用<CR>的旧旧Mac上编辑文件,Unix将不会看到行结尾。如果您在Notepad.exe等Windows程序上编辑文件,您的行将以<CR><LF>结尾,而Unix将假定<CR>是该行的一部分。
  • 所有行必须以<LF>结尾,包括最后一行。如果您使用C程序编写程序,最后一行可能不会以<LF>结尾,除非您专门写出来。

awkgrep这样的Unix实用程序和shell会根据这些假设生存和呼吸。当有人通常告诉我在使用shell脚本读取文件时出现问题时,我告诉他们在VIM中编辑该文件然后保存它(从而强制结束<LF>个字符)。在VIM中,您需要:set ff=unix然后保存。这通常会解决这个问题。

我的猜测是,您正在阅读的文件没有正确的行结尾,和/或最后一行最后没有<LF>个字符。

答案 2 :(得分:0)

我真的不明白你的问题 - 你能告诉我们更多代码/你如何创建文件吗?

这是一个有效的例子:

$ cat readfile.sh
#!/bin/bash

{
        cat <<EOT
this
is
a
test
file
EOT
} > ./test.txt

while read -r line; do
        echo "line = [${line}]"
done <./test.txt

$ ./readfile.sh
line = [this]
line = [is]
line = [a]
line = [test]
line = [file]