Was ist der einfachste Weg, um programmgesteuert aus stdin oder einer Eingabedatei (falls vorhanden) in Perl zu lesen?
Antworten:
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:
program.pl < inputfile
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) { ... }
oder while (<>) { 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 einer while(<>)
Schleife und verarbeitet die Eingabe flexibel.
In slickestWay.pl
:
#! / usr / bin / perl -n START: { # hier mal was machen }} # Logik für eine einzelne Eingabezeile implementieren print $ result;
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
./slickestWay.pl
Lesen Sie aus den in den Argumenten genannten Dateien (keine Umleitung erforderlich).
./slickestWay.pl input.txt
./slickestWay.pl input.txt moreInput.txt
Verwenden Sie ein Rohr
someOtherScript | ./slickestWay.pl
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.
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;
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 ist STDIN
und STDOUT
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($_);
}
$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
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.
$#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(<>);
}
<>
Operator findet und liest automatisch alle in der Befehlszeile angegebenen Dateien. Es gibt keine Notwendigkeit für die if
.
shift
hier tut