如何在不使用`while(<>)`的情况下从STDIN和作为命令行参数传递的文件中读取?

时间:2015-12-07 21:01:11

标签: perl

This post演示了如何从文件中读取<%@ Control CodeBehind="kgfileUploader.aspx.cs" Inherits="SampleUserControl" Language="C#" %> <%@ Register TagPrefix="CuteWebUI" Namespace="CuteWebUI" Assembly="CuteWebUI.AjaxUploader, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bc00d4b0e43ec38d" %> <h3> <u>User Control</u> </h3> <CuteWebUI:Uploader ID="uploader1" runat="server"> </CuteWebUI:Uploader> ,而不使用空文件句柄(即STDIN)。但是,我想知道如何解决输入可能来自文件while(<>)或同时来自两者的情况。

例如,STDIN语法可以处理这种情况,如以下最小示例所示:

<>

如何在不使用$ echo -e 'a\nb\nc' | \ while read x; do echo $x > ${x}".txt"; done; echo "d" | \ perl -e "while(<>) {print;}" {a,b,c}.txt - a b c d 的情况下执行此操作?

我想避免使用while(<>),因为我想独立处理每个文件,而不是将所有输入聚合为单个文本流。此外,我想在没有在每一行输入上测试<>的情况下这样做。

3 个答案:

答案 0 :(得分:1)

如果你想独立处理每个文件,你应该遍历已经给出的参数并依次打开每个文件:

for (@ARGV) {
    open(my $fh, '<', $_) || die "cannot open $_";
    while (<$fh>) {
        ... process the file here ...
    }
}
# handle standard input
while (<STDIN>) {
    ...
}

答案 1 :(得分:1)

这是一个基于Tim的想法,它检查STDIN是否有东西要读(NON BLOCKING STDIN)。如果您并不真正关心用户从STDIN手动输入输入但仍希望能够管道并将数据重定向到脚本,则此功能非常有用。

File: script.pl

#!/usr/bin/env perl 

use IO::Select;

$s = IO::Select->new();
$s->add(\*STDIN);
if ($s->can_read(0)) { push @ARGV, "/dev/stdin"; } 

for (@ARGV) {
    open(IN, "<$_") || die "** Error opening \"$_\": $!\n";
    while (<IN>) {
        print $_
    }
}

$&GT;回声“你好世界”| script.pl
你好世界

$&GT; script.pl&lt; &lt;(回声“你好世界”)
你好世界

$&GT; script.pl&lt;(echo“hello world”)
你好世界

$&GT; script.pl&lt;&lt;&lt; “你好世界”
你好世界

$&GT; script.pl
$&GT;

答案 2 :(得分:0)

问题所在的答案已经回答了这个问题。

@ARGS = '-' if !@ARGV;

for my $qfn (@ARGV) {
    open($fh, $qfn);

    while (<$fh>) {
       ...
    }
}