bash 为什么 unix while read 不读最后一行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20010741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:38:35  来源:igfitidea点击:

Why does unix while read not read last line?

linuxbashshellunix

提问by Popcorn

My script

我的剧本

export IFS=":"

cat hello | while read a b c d; do
    echo $a,$b,$c,$d
done

My file hello

我的档案 hello

1:1:1:1
2:2:2:2
3:3:3:3

My output

我的输出

1,1,1,1
2,2,2,2

If I put a blank line after 3:3:3:3in hellothen the output becomes

如果我在3:3:3:3in后面放一个空行,hello则输出变为

1,1,1,1
2,2,2,2
3,3,3,3

Anyone know how I can fix this problem so I don't need to put a blank line at the end of hello?

任何人都知道我如何解决这个问题,所以我不需要在末尾放一个空行hello

回答by janos

What's happening is, the readcommand fails when the input is not terminated with a newline. Since the newline character is missing at the end of your file, the readfails, so the last iteration of the whileloop is skipped.

发生的情况是,read输入没有以换行符终止时,命令会失败。由于文件末尾缺少换行符read,因此失败,因此while跳过循环的最后一次迭代。

If you don't want to / cannot make sure that your input file has a newline at the end, you can group your catwith an echoto give the appearanceof an input terminated by newline, for example like this:

如果您不想/不能确保您的输入文件末尾有一个换行符,您可以将您的cat与 an分组echo以给出由换行符终止的输入的外观,例如像这样:

{ cat hello; echo; } | while read a b c d; do
    echo $a,$b,$c,$d
done

or like this:

或者像这样:

(cat hello; echo) | while read a b c d; do
    echo $a,$b,$c,$d
done

回答by Jahid

This is an extensive reading for the question why?

这是一个广泛阅读的问题为什么?

If you don't want to put a new line at the end, you can do this:

如果你不想在最后放一个新行,你可以这样做:

while IFS=: read -r a b c d || [ -n "$a" ]; 
do     
echo $a,$b,$c,$d; 
done < file

Or using grep:

或使用grep

while IFS=: read -r a b c d; 
do     
echo $a,$b,$c,$d; 
done < <(grep "" filee)

Note:

笔记:

  1. There's no need to use cat with while loop.
  2. You should almost always use the -r option with read.
  1. 没有必要在 while 循环中使用 cat。
  2. 您几乎应该总是将 -r 选项与 read 一起使用。

回答by user2719058

There exists a not very well-known, nasty hack to append a missing final newline to a text stream if and only if it's missing:

当且仅当它丢失时,存在一个不太知名的、讨厌的 hack 将丢失的最终换行符附加到文本流:

sed '$a\'

See this discussionon unix.stackexchange, for example.

例如,请参阅有关 unix.stackexchange 的讨论

回答by anubhava

It is most likely due to absence of newline character after last line in your input file.

这很可能是由于输入文件中最后一行之后没有换行符。

Run this command to find out:

运行此命令以找出:

cat -vte hello

And see what you get.

看看你得到了什么。

回答by iruvar

Your file is probably missing a newline (\n) on the last line. You can prove this by printing the residual values of $aetc, like so

您的文件可能\n在最后一行缺少换行符 ( )。您可以通过打印等的残值来证明这一点$a,就像这样

while IFS=: read a b c d; 
do     
echo $a,$b,$c,$d; 
done < hello  
echo $a,$b,$c,$d

Fix the file. Also, you should be able to set IFSspecifically for the readas shown above. And no need to catthe file either, just use input redirection as shown

修复文件。此外,您应该能够IFS专门为read如上所示进行设置。也不需要cat文件,只需使用输入重定向,如图所示