Was ist der einfachste Weg, um programmgesteuert aus stdin oder einer Eingabedatei (falls vorhanden) in Perl zu lesen?
74
while (<>) {
print;
}
liest entweder aus einer in der Befehlszeile angegebenen Datei oder aus stdin, wenn keine Datei angegeben ist
Wenn Sie diese Schleifenkonstruktion in der Befehlszeile benötigen, können Sie die folgende -n
Option verwenden:
$ perl -ne 'print;'
Hier setzen Sie einfach Code zwischen {}
dem ersten Beispiel und dem ''
zweiten
@ARGV = "/path/to/some/file.ext";
und die Datei zu lesen - so können Sie unter bestimmten Bedingungen sogar eine Standarddatei programmieren.perl -n -e '$_ = uc($_); print;' yourfile
. Mit -p anstelle von -n druckt Perl am Ende automatisch $ _.my @slurp = <>; foreach my $line (@slurp) { ... }
while (my $line = <>) {...
?Dies bietet eine benannte Variable, mit der gearbeitet werden kann:
foreach my $line ( <STDIN> ) { chomp( $line ); print "$line\n"; }
Um eine Datei zu lesen, leiten Sie sie wie folgt ein:
quelle
foreach my $line ( <STDIN> ) {
Ich stimme @MikeKulls zu. Es ist nicht Perls Schuld, wenn Perl-Skripte nicht lesbar sind. Hier sind Programmierer schuld!while(my $line = <>) { print $line; }
.while (my $line = <>, defined $line) { ... }
oderwhile (<>) { my $line = $_; }
um nicht in einer leeren Zeile stehen zu bleiben ?In bestimmten Situationen ist es am "schicksten", den
-n
Schalter zu nutzen . Es umschließt Ihren Code implizit mit einerwhile(<>)
Schleife und verarbeitet die Eingabe flexibel.In
slickestWay.pl
:In der Kommandozeile:
chmod +x slickestWay.pl
Führen Sie nun abhängig von Ihrer Eingabe einen der folgenden Schritte aus:
Warten Sie auf Benutzereingaben
Lesen Sie aus den in den Argumenten genannten Dateien (keine Umleitung erforderlich).
Verwenden Sie ein Rohr
Der
BEGIN
Block ist erforderlich, wenn Sie eine objektorientierte Schnittstelle wie Text :: CSV oder eine andere initialisieren müssen, mit der Sie dem Shebang hinzufügen können-M
.-l
und-p
sind auch deine Freunde.quelle
Sie müssen den Operator <> verwenden:
while (<>) { print $_; # or simply "print;" }
Welches kann verdichtet werden, um:
print while (<>);
Beliebige Datei:
open F, "<file.txt" or die $!; while (<F>) { print $_; } close F;
quelle
Wenn es einen Grund gibt, warum Sie die von ennuikiller oben bereitgestellte einfache Lösung nicht verwenden können , müssen Sie Typeglobs verwenden, um Dateihandles zu bearbeiten. Das ist viel mehr Arbeit. Dieses Beispiel kopiert von der Datei in
$ARGV[0]
die in$ARGV[1]
. Der Standardwert istSTDIN
undSTDOUT
jeweils , wenn die Dateien nicht angegeben werden.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($_); }
quelle
$ARGV[0]
usw. durch eine andere Variable), wo alle anderen Antworten fehlschlagen ...unshift
den Dateinamen auf@ARGV
und verwenden Sie den Diamantoperator<>
.Machen
$userinput = <STDIN>; #read stdin and put it in $userinput chomp ($userinput); #cut the return / line feed character
wenn Sie nur eine Zeile lesen möchten
quelle
Hier ist, wie ich ein Skript erstellt habe, das entweder Befehlszeileneingaben annehmen oder eine Textdatei umleiten lassen kann.
if ($#ARGV < 1) { @ARGV = (); @ARGV = <>; chomp(@ARGV); }
Dadurch wird der Inhalt der Datei @ARGV neu zugewiesen. Von dort aus verarbeiten Sie @ARGV einfach so, als würde jemand Befehlszeilenoptionen einschließen.
WARNUNG
Wenn keine Datei umgeleitet wird, bleibt das Programm im Leerlauf, da es auf die Eingabe von STDIN wartet.
Ich habe noch keine Möglichkeit gefunden, festzustellen, ob eine Datei umgeleitet wird, um das STDIN-Problem zu beheben.
quelle
$#ARGV < 1
statt (was ich als) klarer@ARGV == 1
?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(<>); }
quelle
<>
Operator findet und liest automatisch alle in der Befehlszeile angegebenen Dateien. Es gibt keine Notwendigkeit für dieif
.shift
hier tut