2010-06-29 90 views

回答

72
while (<>) { 
print; 
} 

將讀取從在t上指定的文件他命令行或標準輸入,如果如果你需要在命令行這個循環結構沒有給出文件

,那麼你可以使用-n選項:

$ perl -ne 'print;' 

在這裏,你只要把從第一個例子{}之間的代碼進入第二

+21

+1 + nitpick:「將從命令行上連續指定的一個或多個文件中讀取」 – msw 2010-06-29 07:57:31

+4

...並且您需要做的就是編寫「@ARGV =」/path/to/some/file.ext 「;它讀取文件 - 所以你甚至可以在某些條件下編程一個默認文件。 – Axeman 2010-06-29 13:54:05

+2

如果腳本非常短,可以使用-n或-p選項來perl,並在命令行上指定處理: 'perl -n -e'$ _ = uc($ _);打印;' yourfile'。用-p代替-n,perl自動在最後打印$ _。 – mivk 2012-01-09 10:46:19

12

您需要使用<>運營商:

while (<>) { 
    print $_; # or simply "print;" 
} 

這可以壓縮到:

print while (<>); 

任意文件:

open F, "<file.txt" or die $!; 
while (<F>) { 
    print $_; 
} 
close F; 
-2
if(my $file = shift) { # if file is specified, read from that 
    open(my $fh, '<', $file) or die($!); 
    while(my $line = <$fh>) { 
    print $line; 
    } 
} 
else { # otherwise, read from STDIN 
    print while(<>); 
} 
+7

普通的'<>'操作符會自動從命令行中給出的任何文件中查找和讀取。沒有必要使用'if'。 – 2010-06-29 08:27:16

+0

你也沒有描述'shift'在這裏做什麼 – 2017-07-08 13:14:32

6

''

$userinput = <STDIN>; #read stdin and put it in $userinput 
chomp ($userinput); #cut the return/line feed character 

,如果你想讀的只有一行

+0

只從STDIN讀取,而不是從指定的文件讀取。鑽石操作員*完全* OP所要查找的內容。 – 2018-01-20 23:14:36

34

這提供了一個名爲變量一起工作:

foreach $line (<STDIN>) { 
    chomp($line); 
    print "$line\n"; 
} 

要讀取一個文件,管道就在這樣的:

program.pl < inputfile 
+7

+1,用於避免所有太常見的速記不可讀的Perl代碼 – MikeKulls 2013-12-11 23:55:00

+3

-1因爲foreach會啜泣整個文件。最好在while循環中分配給該行。此外,Perl內置了尖角括號的神奇行爲,所以你應該說while(my $ line = <>)。那麼不需要重定向。 – 2014-07-07 16:12:27

+2

第一行應爲'foreach my $ line(){' 我同意@MikeKulls。如果Perl腳本不可讀,這不是Perl的錯。程序員應該責怪這裏! – tiktak 2014-12-13 13:01:12

10

的在某些情況下,「最清晰」的方式是利用-n switch。它隱式地用while(<>)循環包裝您的代碼並靈活地處理輸入。

slickestWay.pl

 
#!/usr/bin/perl -n 

BEGIN: { 
    # do something once here 
} 

# implement logic for a single line of input 
print $result; 

在命令行:

chmod +x slickestWay.pl 

現在,根據您的輸入請執行下列操作之一:

  1. 等待用戶輸入

    ./slickestWay.pl 
    
  2. 從參數命名的文件(S)閱讀(無需重定向)

    ./slickestWay.pl input.txt 
    ./slickestWay.pl input.txt moreInput.txt 
    
  3. 使用管道

    someOtherScript | ./slickestWay.pl 
    

BEGIN塊是必要的,如果你需要初始化某種面向對象的接口,例如Text :: CSV或其他一些,您可以使用-M添加到shebang。

-l and -p也是你的朋友。

5

如果你有一個原因不能使用上面提供的ennuikiller提供的簡單解決方案,那麼你將不得不使用Typeglobs來操作文件句柄。這是更多的工作。此示例從$ARGV[0]中的文件複製到$ARGV[1]中的文件中。如果未指定文件,它將分別默認爲STDINSTDOUT

use English; 

my $in; 
my $out; 

if ($#ARGV >= 0){ 
    unless (open($in, "<", $ARGV[0])){ 
     die "could not open $ARGV[0] for reading."; 
    } 
} 
else { 
    $in = *STDIN; 
} 

if ($#ARGV >= 1){ 
    unless (open($out, ">", $ARGV[1])){ 
     die "could not open $ARGV[1] for writing."; 
    } 
} 
else { 
    $out = *STDOUT; 
} 

while ($_ = <$in>){ 
    $out->print($_); 
} 
+0

對於一種可以工作的方式,如果從*中讀取的文件名不是在命令行中提供的,而是在其他地方提供的(在某些變量中,從配置文件等中讀取 - 只需用其他變量替換「$ ARGV [0] )其中所有其他答案都失敗...... – 2016-10-30 16:29:46

+0

或者,對於閱讀,只需'將'文件名'轉移'到'@ ARGV'並使用菱形運算符'<>'。 – 2018-01-20 23:04:53

0

這裏是我做了一個腳本,可以採取以下命令行輸入或具有重定向的文本文件。就好像有人,包括命令行選項

if ($#ARGV < 1) { 
    @ARGV =(); 
    @ARGV = <>; 
    chomp(@ARGV); 
} 


這將重新分配給@ARGV文件的內容,從那裏你只是過程@ARGV。

警告

如果沒有文件重定向,因爲它是從標準輸入等待輸入程序將坐在自己的閒置。

我還沒有想出一種方法來檢測文件是否被重定向到還沒有消除STDIN問題。

+0

這是一個很酷的方法,但不是OP要求的。這使得傳遞單個文件名作爲參數成爲可能,其中的內容被用作命令行參數。 OP正在尋找不同的東西。此外,爲什麼隱藏的'$#ARGV <1'而不是(我認爲)更清晰的'@ARGV == 1'? – 2018-01-20 23:12:58