带有 $ 的当前文件行号.多变的 [英] Current file line number with $. variable

查看:55
本文介绍了带有 $ 的当前文件行号.多变的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我可以使用内置变量 $. 获取正在循环的文件的当前行号.作为一个实验,我用它来为文件中的每一行加上 $.(当前行号)的值作为前缀.然而,这并没有按预期工作.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆