带有 $ 的当前文件行号.多变的 [英] Current file line number with $. variable
问题描述
我知道我可以使用内置变量 $.
获取正在循环的文件的当前行号.作为一个实验,我用它来为文件中的每一行加上 $.
(当前行号)的值作为前缀.然而,这并没有按预期工作.IE.给定以下文件内容
I understand that I can get the current line number of a file I am looping through with the builtin variable $.
. As an experiment, I used that to prefix each line in a file with the value of $.
(the current line number). However, this did not work as expected. I.e. given the following file contents
line one
line two
line three
然后我希望以下代码在每行前面加上行号
then I would expect the following code to prefix each line with its line number
for my $line (<FILE>) {
print "$. : $line";
}
但是,它给出了以下输出
but, instead, it gives the following output
3 line one
3 line two
3 line three
用文件中的行数作为每行的前缀.而不是当前行.
prefixing each line with the number of lines in the file. Instead of the current line.
推荐答案
那是因为您编写循环的方式是在遍历行之前读取整个文件.除非您有特殊原因需要比简单顺序访问文件更好的东西,否则您应该使用 while
而不是 for
,如下所示:
That's because the way you wrote the loop reads the entire file before looping over the lines. Unless you have a special reason to need something better than simple sequential access to the file, you should use while
instead of for
, like this:
while (my $line = <FILE>) {
print "$. : $line";
}
当 <
filehandle >
在列表上下文中被调用时(就像在你的 for
循环中一样),它将文件的全部内容作为行列表返回.因此,您的代码的行为方式与您编写的代码大致相同:
When <
filehandle >
is called in list context (as it is in your for
loop), it returns the entire contents of the file as a list of lines. Therefore, your code behaves in much the same way as if you had written this instead:
my @lines = <FILE>; # now $. is set to the end of the file
for my $line (@lines) { ... } # you're just looping over an array, not touching $.
为了达到您想要的结果,您应该在标量上下文中重复调用 <>
(while
条件中的赋值就是这样做的),以在从文件中提取时间,并使用 $.
设置为正确的数字来执行循环体.
To achieve your desired result, you should call <>
repeatedly in scalar context (which the assignment in the while
condition does), to fetch one line at a time from the file and execute the body of the loop with $.
set to the correct number.
此外,全局文件句柄被认为是不好的做法.出于多种原因,最好使用由词法变量引用的文件句柄,如下所示:
Also, global filehandles are considered to be bad practice. For several reasons, it's better to use a filehandle referenced by a lexical variable instead, like this:
open my $file, '<', $filename or die $!;
while (my $line = <$file>) {
print "$. : $line";
}
此外,由于 $.
是一个 全局 变量,其中包含来自最近执行的 读取操作的行号,因此您不应该如果 <$file>
和 print
之间有可能发生另一次读取,请依赖它.相反,询问您正在使用的文件句柄它的行号:
Also also, since $.
is a global variable containing the line number from the most recently executed read operation, you shouldn't rely on it if there's any chance of another read occurring between the <$file>
and the print
. Instead, ask the filehandle you're using for its line number:
open my $file, '<', $filename or die $!;
while (my $line = <$file>) {
print $file->input_line_number, " : $line";
}
使用全局文件句柄甚至更笨拙的工作:
Which even works, if somewhat more awkwardly, with a global filehandle:
while (my $line = <FILE>) {
print ${\*FILE}->input_line_number, " : $line";
}
...即使是默认的由一个空的<>
读取,它实际上被命名为ARGV
:
... even the default one read by an empty <>
, which is really named ARGV
:
while (my $line = <>) {
print ${\*ARGV}->input_line_number, " : $line";
}
这篇关于带有 $ 的当前文件行号.多变的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!