Wie kann ich den gesamten Text vor der Übereinstimmung in einer Perl -Substitution ersetzen?

StackOverflow https://stackoverflow.com/questions/998193

  •  14-09-2019
  •  | 
  •  

Frage

Ich lese jede Zeile einer Eingabedatei (IN) und drucke die Zeile in einer Ausgabedatei (OUT), wenn die Zeile mit einem der Muster beginnt, sagen "AB", "CD", "EF", "GH" , "ij" usw. Die gedruckte Linie hat Form "Muster: 100" oder Form "Muster: 100: 200". Ich muss "Muster" durch "myPattern" ersetzen, dh die aktuelle Zeile drucken, um zu filmen, aber den gesamten Text vor dem ersten Ereignis von ":" mit "mypattern" ersetzen. Was ist der beste Weg, dies zu tun?

Derzeit habe ich:

while ( <IN> )
{ 
    print FILE if /^ab:|^bc:|^ef:|^gh:/;
}

Ich bin mir nicht sicher, ob der Substr -Ersatz als "Muster" helfen würde, entweder "AB" oder "CD" oder "EF" oder "GH" usw. zu sein.

Vielen Dank! Bi

War es hilfreich?

Lösung

sub replacer {

    $line = shift;
    $find = shift;
    $replace = shift;

    $line =~ /([^:]+):/
    if ($1 =~ /$find/) { 
         $line =~ s/([^:]+):/$replace/ ;
         return $line;      
    }
    return ;

}

while (<IN>)
{
    print OUT replacer ($_,"mean","variance");
    print OUT replacer ($_,"pattern","newPattern");
}

Mein Perl ist ein wenig verrostet, daher ist die Syntax möglicherweise nicht genau.

bearbeiten: Setzen Sie es in eine Funktion für ya.

Andere Tipps

Tun Sie dies generell wie:

my %subst = ( 'ab' => 'newab', 'bc' => 'newbc', 'xy' => 'newxy' );
my $regex = join( '|', map quotemeta, sort { length($b) <=> length($a) } keys %subst );
$regex = qr/^($regex):/;

while ( <IN> ) {
    print FILE if s/$regex/$subst{$1}:/;
}

Die Sortierung setzt die längsten an erster Stelle, sodass AB: Wenn die Daten ab :: und sowohl AB als auch AB ersetzt werden, werden ab: anstelle von AB verwendet.

Perls Substitutionsbetreiber standardmäßig (a) verwendet die erste Übereinstimmung, (b) nur eine Übereinstimmung ersetzt und (c) true zurückgegeben, wenn ein Ersatz erstellt wurde und falsch ist, wenn dies nicht der Fall war.

So:

while ( <IN> )
{ 
    if (s/<pattern1>:/<replace1>/ ||
        s/<pattern2>:/<replace2>/) {
       print FILE;
    }
}

Sollte für Sie arbeiten. Beachten Sie, dass aufgrund des Kurzschlusss nur eine Substitution erfolgt.

while ( <IN> )
{ 
  s/^pattern:/myPattern:/;
  print OUT
}

Dies könnte das sein, was Sie wollen:

$expr = "^(ab)|(cd)|(ef)|(gh)|(ij)";
while (<IN>)
{
    if (/$expr:/)
    {
        s/$expr/$myPattern/;
        print FILE;
    }
}

Der kürzeste Weg, um das zu tun, was Sie oben fragen, besteht darin, Ihren Code wiederzuverwenden, aber eine Substitution einzuschließen.

while ( <IN> )
{ 
    print FILE if s/^(ab|bc|ef|gh):/MyPattern:/;
}

Jedes der linken Seite wird ersetzt. Wenn die linke Seite nicht übereinstimmt, wird nichts gedruckt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top