如何从命令行获取文件句柄?

发布于 2024-07-06 19:52:08 字数 378 浏览 8 评论 0原文

我有一个以文件句柄作为参数的子例程。 如何从命令行指定的文件路径创建文件句柄? 我不想自己对这个文件进行任何处理,我只想将其传递给另一个子例程,该子例程返回一个包含文件中所有解析数据的哈希数组。

我使用的命令行输入如下所示:

$ ./getfile.pl /path/to/some/file.csv

这是我调用的子例程的开头如下所示:

sub parse {
    my $handle = shift;
    my @data   = <$handle>;
    while (my $line = shift(@data)) {
      # do stuff
    }
}

I have a subroutine that takes a filehandle as an argument. How do I make a filehandle from a file path specified on the command line? I don't want to do any processing of this file myself, I just want to pass it off to this other subroutine, which returns an array of hashes with all the parsed data from the file.

Here's what the command line input I'm using looks like:

$ ./getfile.pl /path/to/some/file.csv

Here's what the beginning of the subroutine I'm calling looks like:

sub parse {
    my $handle = shift;
    my @data   = <$handle>;
    while (my $line = shift(@data)) {
      # do stuff
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

猥琐帝 2024-07-13 19:52:08

命令行参数在预定义的@ARGV 数组中可用。 您可以从那里获取文件名并使用 open 打开它的文件句柄。 假设您想要对该文件进行只读访问,您可以这样做:

my $file = shift @ARGV;
open(my $fh, '<', $file) or die "Can't read file '$file' [$!]\n";
parse($fh);

请注意,or die... 检查调用 open 是否成功,并以以下方式结束:如果不是,则显示错误消息。 内置变量 $! 将包含失败时的(取决于操作系统)错误消息,告诉您调用不成功的原因。 例如“权限被拒绝”。

Command line arguments are available in the predefined @ARGV array. You can get the file name from there and use open to open a filehandle to it. Assuming that you want read-only access to the file, you would do it this way:

my $file = shift @ARGV;
open(my $fh, '<', $file) or die "Can't read file '$file' [$!]\n";
parse($fh);

Note that the or die... checks the call open for success and dies with an error message if it wasn't. The built-in variable $! will contain the (OS dependent) error message on failure that tells you why the call wasn't successful. e.g. "Permission denied."

静待花开 2024-07-13 19:52:08

parse(*ARGV) 是最简单的解决方案:解释有点长,但是学习如何有效使用 Perl 的一个重要部分就是学习 Perl。

当您使用空文件句柄 (<>) 时,它实际上从神奇的 ARGV 文件句柄中读取,该文件句柄具有特殊的语义:它从 <> 中命名的所有文件读取。 code>@ARGV,如果 @ARGV 为空,则为 STDIN

来自perldoc perlop:

空文件句柄<>很特殊:它可以用来模拟
sed 和 awk 的行为。 <> 的输入来自标准
输入,或来自命令行上列出的每个文件。 是这样的
有效:第一次计算 <> 时,检查 @ARGV 数组,并且
如果为空,则 $ARGV[0] 设置为 "-",打开后会为您提供
标准输入。 然后将 @ARGV 数组作为列表进行处理
文件名。 循环

while (<>) { 
      ... # 每行代码 
  } 
  

相当于以下类似 Perl 的伪代码:

unshift(@ARGV, '-') 除非 @ARGV; 
  而($ARGV = 移位){ 
      打开(ARGV,$ARGV); 
      而 () { 
          ... # 每行代码 
      } 
  } 
  

只不过说起来并不那么麻烦,并且实际上会起作用。 它
确实会移动 @ARGV 数组并将当前文件名放入
$ARGV 变量。 它还在内部使用文件句柄 ARGV - <> 只是一个
的同义词,这很神奇。 (上面的伪代码没有
有效,因为它将 视为非魔法。)

您不必在 while 循环中使用 <> -- my $data = <> 将从第一个非空文件中读取一行,my @data = <>; 会将其全部吞掉立即,您可以传递 *ARGV ,就好像它是一个普通的文件句柄一样。

parse(*ARGV) is the simplest solution: the explanation is a bit long, but an important part of learning how to use Perl effectively is to learn Perl.

When you use a null filehandle (<>), it actually reads from the magical ARGV filehandle, which has special semantics: it reads from all the files named in @ARGV, or STDIN if @ARGV is empty.

From perldoc perlop:

The null filehandle <> is special: it can be used to emulate the
behavior of sed and awk. Input from <> comes either from standard
input, or from each file listed on the command line. Here’s how it
works: the first time <> is evaluated, the @ARGV array is checked, and
if it is empty, $ARGV[0] is set to "-", which when opened gives you
standard input. The @ARGV array is then processed as a list of
filenames. The loop

while (<>) {
    ...                     # code for each line
}

is equivalent to the following Perl-like pseudo code:

unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift) {
    open(ARGV, $ARGV);
    while (<ARGV>) {
        ...         # code for each line
    }
}

except that it isn’t so cumbersome to say, and will actually work. It
really does shift the @ARGV array and put the current filename into the
$ARGV variable. It also uses filehandle ARGV internally--<> is just a
synonym for <ARGV>, which is magical. (The pseudo code above doesn’t
work because it treats <ARGV> as non-magical.)

You don't have to use <> in a while loop -- my $data = <> will read one line from the first non-empty file, my @data = <>; will slurp it all up at once, and you can pass *ARGV around as if it were a normal filehandle.

下雨或天晴 2024-07-13 19:52:08

这就是 -n 开关的用途!

采用您的解析方法,并执行以下操作:

#!/usr/bin/perl -n

#do stuff

每一行都存储在 $_ 中。 所以你运行

./getfile.pl /path/to.csv

它会这样做。

请参阅此处此处了解有关这些的更多信息。 我也喜欢 -p,并且发现 -a 和 -F 的组合非常有用。

另外,如果您想进行一些额外的处理,请添加 BEGIN 和 end 块。

#!/usr/bin/perl -n

BEGIN {
  my $accumulator;
}

# do stuff

END {
  print process_total($accumulator);
}

管他呢。 这非常非常有用。

This is what the -n switch is for!

Take your parse method, and do this:

#!/usr/bin/perl -n

#do stuff

Each line is stored in $_. So you run

./getfile.pl /path/to.csv

And it does this.

See here and here for some more info about these. I like -p too, and have found the combo of -a and -F to be really useful.

Also, if you want to do some extra processing, add BEGIN and end blocks.

#!/usr/bin/perl -n

BEGIN {
  my $accumulator;
}

# do stuff

END {
  print process_total($accumulator);
}

or whatever. This is very, very useful.

心如荒岛 2024-07-13 19:52:08

我是否遗漏了某些内容,或者您​​只是在寻找 open() 调用?

open($fh, "<$ARGV[0]") or die "couldn't open $ARGV[0]: $!";
do_something_with_fh($fh);
close($fh);

Am I missing something or are you just looking for the open() call?

open($fh, "<$ARGV[0]") or die "couldn't open $ARGV[0]: $!";
do_something_with_fh($fh);
close($fh);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文