Программно читать из STDIN или входного файла в Perl - PullRequest
63 голосов
/ 29 июня 2010

Каков самый удобный способ программного чтения из стандартного ввода или входного файла (если имеется) в Perl?

Ответы [ 8 ]

77 голосов
/ 29 июня 2010
while (<>) {
print;
}

будет читать либо из файла, указанного в командной строке, либо из стандартного ввода, если файл не указан

Если вам требуется эта конструкция цикла в командной строке, тогда вы можете использовать -n параметр:

$ perl -ne 'print;'

Здесь вы просто помещаете код между {} из первого примера в '' во втором

44 голосов
/ 15 февраля 2013

Это обеспечивает именованную переменную для работы:

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

Чтобы прочитать файл, передайте его так:

program.pl < inputfile
14 голосов
/ 10 февраля 2014

В некоторых ситуациях «изящным» способом является использование переключателя -n . Он неявно оборачивает ваш код циклом 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. Чтение из файла (ов) с именами в аргументах (перенаправление не требуется)

    ./slickestWay.pl input.txt
    ./slickestWay.pl input.txt moreInput.txt
    
  3. Использовать трубу

    someOtherScript | ./slickestWay.pl 
    

Блок BEGIN необходим, если вам нужно инициализировать некоторый объектно-ориентированный интерфейс, такой как Text :: CSV или другой, который вы можете добавить в shebang с помощью -M.

-l и -p также ваши друзья.

13 голосов
/ 29 июня 2010

Вам необходимо использовать оператор <>:

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

Который может быть сжат до:

print while (<>);

Произвольный файл:

open F, "<file.txt" or die $!;
while (<F>) {
    print $_;
}
close F;
8 голосов
/ 07 декабря 2014

Если есть причина, по которой вы не можете использовать простое решение, предоставленное ennuikiller выше, вам придется использовать Typeglobs для манипуляции с дескрипторами файлов.Это намного больше работы.Этот пример копирует из файла в $ARGV[0] в файл в $ARGV[1].По умолчанию STDIN и STDOUT соответственно, если файлы не указаны.

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($_);
}
6 голосов
/ 24 января 2013

Do

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

если вы хотите прочитать только одну строку

0 голосов
/ 20 сентября 2015

Вот как я создал скрипт, который может принимать либо входные данные командной строки, либо перенаправлять текстовый файл.

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


Это переназначит содержимое файла на @ARGV, оттуда вы просто обрабатываете @ARGV, как если бы кто-то включал параметры командной строки.

ПРЕДУПРЕЖДЕНИЕ

Если файл не перенаправлен, программа будет бездействовать, так как ожидает ввода от STDIN.

Я не нашел способа определить, был ли файл перенаправлен, чтобы устранить проблему с STDIN.

0 голосов
/ 29 июня 2010
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(<>);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...