Kann ich Lesen und schreiben auf mehrere filehandles gleichzeitig (Perl)?
Ich versuche zu Lesen, aus zwei Dateien, und generieren Sie die Ausgabe in eine Dritte. Ich wollte zuerst Bearbeiten Sie die ersten sind die gehen, aber ich nicht finden, eine geeignete Methode zu speichern, die für arrays.
Mein problem ist, dass die Dritte Datei (Ausgabe) leer ist, wenn ich die Auskommentierung der "_ref_param_handling" - Funktion. ABER das folgende ist, was verwirrt mich am meisten: Wenn ich ein UNIX sehr einfachen `cat` system call auf die Ausgabe-Datei an dann ist Ende (siehe code unten), funktioniert es Prima. Wenn ich öffnen Sie das filehandle kurz vor und schließen Sie es sofort nach der Bearbeitung, es funktioniert auch (um mein print FILEHANDLE LISTE).
Ich zweifellos bin hier etwas fehlt. Abgesehen von einem problem zwischen meiner Tastatur und meinem Stuhl, was ist es? Ein filehandle Konflikt? Ein scope problem?
Jede variable ist deklariert und hat den Wert ich will es haben.
Bearbeiten (gilt nicht mehr).
Mit IO::File auf die drei Dateien nichts verändert.
Edit 2 : New full-code-Unterroutine
Mein code funktioniert (außer, wenn mein ref ist bereits vorhanden, aber das ist, weil der "append" - Modus glaube ich), aber möglicherweise gibt es einige Fehler und unperlish Arten der Kodierung (sorry, Mönche). Ich, jedoch, use Strict und warnings !
sub _ref_edit($) {
my $manda_def = "$dir/manda_def.list";
my $newrefhandle;
my $ref = $_[0];
(my $refout = $ref) =~ s/empty//;
my $refhandle;
my $parname = '';
my $parvalue = '';
my @val;
_printMan;
my $flush = readline STDIN; # Wait for <enter>
# If one or both of the ref. and the default values are missing
if ( !( -e $manda_def && -e $ref ) ) {
die "Cannot find $ref and/or $manda_def";
}
# Open needed files (ref & default)
open( $refhandle, "<", $ref ) or die "Cannot open ref $ref : $!";
open( $newrefhandle, ">>", $refout )
or die "Cannot open new ref $refout : $!";
# Read each line
while ( my $refline = <$refhandle> ) {
# If line read not an editable macro
if ( $refline =~ /^define\({{(.+)}},\s+{{.*__VALUE__.*}}\)/){
$parname = $1; # $1 = parameter name captured in regexp
# Prompt user
$parvalue = _ref_param_handling( $parname, $manda_def );
# Substitution in ref
$refline =~ s/__VALUE__/$parvalue/;
# Param not specified and no default value
$parvalue eq '' ? $refline=~s/__COM__/#/: $refline=~s/__COM__//;
}
print $newrefhandle $refline;
}
close $newrefhandle;
close $refhandle;
return $refout;
} # End ref edit
den _ref_param_handle Unterprogramm noch ist :
open( $mde, '<', $_[1] )
or die "Cannot open mandatory/default list $_[1] : $!";
# Read default/mandatory file list
while (<$mde>) {
( $name, $manda, $default, $match, $descript ) = split( /\s+/, $_, 5 );
next if ( $name !~ $ref_param ); # If param read differs from parname
(SOME IF/ELSE)
} # End while <MDE>
close $mde;
return $input;
}
Auszug aus manda_def Datei :
NAME Mandatory? Default Match Comm.
PORT y NULL ^\d+$ Database port
PROJECT y NULL \w{1,5} Project name
SERVER y NULL \w+ Server name
modemRouting n NULL .+
modlib y bin .+
modules y sms .+
Auszug aus ref_file :
define({{PORT}}, {{__VALUE__}})dnl
define({{PROJECT}}, {{__VALUE__}})dnl
define({{SERVER}}, {{__VALUE__}})dnl
define({{modemRouting}}, {{__COM__{{$0}} '__VALUE__'}})dnl
define({{modlib}}, {{__COM__{{$0}} '__VALUE__'}})dnl
define({{modules}}, {{__COM__{{$0}} '__VALUE__'}})dnl
Jede Hilfe dankbar.
- Immer starten Sie Ihre Perl-Programme mit "
use strict;
" und "use warnings'
". - Ich ! Dies ist nur ein Teil von eine Unterroutine.
- Ich glaube, ich verstehe, was du meinst zu tun. Immer noch nicht wissen, ob Sie möchten, dass alle diejenigen, die {{}} ersetzt, gedacht. Na ja, Sie sagen, das klappt schon, außer '>>'? Welche Fehler haben Sie?
- Hey Leonardo, vielen Dank für Ihre Antwort. Ich möchte nicht, dass meine
{{' or
}}' ersetzt, Sie sind meine m4-Kommentar-Trennzeichen. Ich habe tatsächlich eine unendliche Schleife schreiben, die beim Zugriff auf eine vorhandene ref_file mit '>>', aber verschwenden Sie keine Zeit auf diese. Ich bin ruft $EDITOR (oder vi) statt der Aufforderung line-by-line (nur bei der Angabe einer bereits vorhandenen ref_file). Auf diese Weise kann der Benutzer ändern, was auch immer er braucht.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist unklar, was die Initialisierung der
$refhandle
,$newrefhandle
und$mde
. Abhängig von den Werten, die Sie haben, beeinflussen das Verhalten von öffnen, D. H. ob es in der Nähe alle filehandles, bevor eine neue zu öffnen.Ich würde vorschlagen, dass Sie beginnen mit der
IO::File
- Schnittstelle zu öffnen/schreiben von Dateien, da dies macht die Aufgabe der filehandle-management viel einfacher, und vermeiden unbeabsichtigte schließt. So etwas wie...So weit wie das Bearbeiten von Dateien geht, dies ist ein häufiges Muster, das ich verwenden, um dies zu erreichen, stellen Sie sicher, dass der
-i
Verhalten von perl.öffnen Sie die zweite Datei-handle für die Eingabe außerhalb der Schleife und übergeben Sie eine Referenz auf die subroutine _ref_param_handle.Verwenden Sie suchen-Funktion zum suchen der Datei wieder zu starten.
Wenn Ihre Datei nicht zu groß ist können Sie auch der Speicherung der Inhalte in ein array und der Zugriff auf Sie anstelle von Schleifen über denselben Inhalt.
EDIT:
Hier ist ein kleines Beispiel, um zu unterstützen, was ich zu sagen versuchte über:
Info über perl Referenzen
Von dem, was ich sammeln, Ihr Skript umwandeln will eine Datei in der folgenden form:
etwas wie dies:
Folgende Werke. Ich weiß nicht, was manda_def bedeutet, und auch ich wollte nicht stören zu erstellen, die eine wirkliche variable Ersatz-Funktion.
Jungs, ich ernsthaft in Erwägung ziehen, hängen mich mit meiner drahtlosen Maus.
Mein Skript nie gescheitert. Ich wollte nur nicht, es lief bis zum Ende (es ist eigentlich eine sehr lange parameter-Liste). Der Druck ist gerade fertig, sobald das filehandle geschlossen ist (oder so dachte ich)...
/mich *weint*
Habe ich damit verbracht, 24 Stunden auf dieser...