2014-03-04 81 views
1

我想要做的工作是用“While ... do ... done”循环从文本文件中读取一行(目前该文件只包含一行,后面会增加行数)。奇怪的是它只能读取一些文本文件。我的代码是:为什么“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”之后,如果我修改并将其保存在当前目录中,然后运行我的脚本,它通常也可以打印“标志”。

除上述两种情况外,其他情况下我的脚本不能打印“标志”。 我也尝试在我的脚本中“chmod”和“touch”文本文件,就像下面这样,它也无法工作。

显然,我希望我的脚本能够读取文本文件的行,是否有人可以告诉我原因并提供解决方案?

顺便说一下,这个文件可以通过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”结尾添加“< <”\ n“”即可。该线变为,

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

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

+0

我不知道'bash'scripting,但我想也许在你创建文件后,缓冲区没有被刷新,所以文件没有完全写入 – Zaiborg

+4

你的脚本对我来说工作正常 - 你如何创建文件? –

+0

@Zaiborg:文件只能在单个进程中不能刷新。由于每个shell命令都是独立的进程,这不是一个问题。 –

回答

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] 
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循环在文件中每行打印一条消息,因此如果没有行(并且touch不会添加任何),则(该脚本是您发布内容的精确副本,除了触摸被替换为某些内容)它显然不会打印任何东西。

1

我在这里采取了猜测:

在Unix中,两个假设都是关于文本文件提出:

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

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

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

+0

我的情况正如你所猜测的。请参阅上面我的帖子的最后部分。 – user2740039

+0

@ user2740039那就别忘了接受David的回答! :-) –