„falsches Flag im Ersetzungsbefehl: '{“ beim Ersetzen einer Zeichenfolge mit sed von einer Datei in eine andere Datei

„falsches Flag im Ersetzungsbefehl: '{“ beim Ersetzen einer Zeichenfolge mit sed von einer Datei in eine andere Datei

Ich versuche, die in Datei1 gefundenen Zeichenfolgen durch Zeichenfolgen in Datei2 zu ersetzen

Datei1

<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2011/03/27&amp;EntityID=Ad12911&amp;imgExtension=" />
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2011/03/20&amp;EntityID=Ad13304&amp;imgExtension=" />
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2010/08/29&amp;EntityID=Ad13724&amp;imgExtension=" />

Datei2

/getimage.dll?path=Orange/2011/03/27/129/Img/Ad1291103.gif
/getimage.dll?path=Orange/2011/03/20/133/Img/Ad1330402.gif
/getimage.dll?path=Orange/2010/08/29/137/Img/Ad1372408.gif

Wenn ich diesen Befehl ausführe

$ sed -e 's/.*SRC="\/Repository\([^"]*\)".*/\1/p{r File1' -e 'd}' File2

Ich erhalte diesen Fehler

sed: 1: "s/.*SRC="\/Repository\( ...": bad flag in substitute command: '{'

Stimmt etwas mit meinem regulären Ausdruck nicht?

Das Ergebnis, das ich erreichen möchte, wäre, dass Datei1 folgendermaßen aussieht:

Datei1

<IMG SRC="/Repository/getimage.dll?path=Orange/2011/03/27/129/Img/Ad1291103.gif" />
<IMG SRC="/Repository/getimage.dll?path=Orange/2011/03/20/133/Img/Ad1330402.gif" />
<IMG SRC="/Repository/getimage.dll?path=Orange/2010/08/29/137/Img/Ad1372408.gif" />

Antwort1

Wenn Sie versuchen, File1alles in Anführungszeichen durch neue, von dort übernommene Bildnamen zu ersetzen File2, würde ich awk verwenden:

awk -F'"' 'NR==FNR{a[i++]=$1;next}{print $1 FS a[j++] FS $3}' File2 File1

Die Ausgabe ist wie folgt:

<IMG SRC="/getimage.dll?path=Orange/2011/03/27/129/Img/Ad1291103.gif" />
<IMG SRC="/getimage.dll?path=Orange/2011/03/20/133/Img/Ad1330402.gif" />
<IMG SRC="/getimage.dll?path=Orange/2010/08/29/137/Img/Ad1372408.gif" />

Antwort2

Ich habe keine Ahnung, was Sie da versuchen, aber mein Sed-Fu ist nicht so stark, also nehme ich an, Sie verwenden eine geheimnisvolle Syntax, die ich nicht kenne. Da ich Ihnen nicht sagen kann, was mit Ihrem Sed nicht stimmt (aber eine fundierte Vermutung ist, dass die Sonderzeichen in Ihren Ersetzungszeichenfolgen ( /usw. ?) Probleme verursachen), biete ich stattdessen eine Perl-Alternative an:

perl -i -pe 'BEGIN{open($f,shift); while(<$f>){chomp; push @F,$_}}
            $k=shift(@F); s/(.*SRC=.)([^"]*)/$1$k/' file2 file1 

Hier ist dasselbe als kommentiertes Skript geschrieben, um es klarer zu machen. Im Einzeiler oben -ibewirkt das , dass die eigentliche Eingabedatei geändert wird, genau wie sed -i.

#!/usr/bin/env perl

## This is the equivalent of the BEGIN{} block.
## @ARGV is the array of arguments and shift returns
## the first element of it. This is file2 which is
## then opened, each line is read, its trailing \n
## is removed by chomp and it is then added to the @F array.
my $file=shift(@ARGV);
open($f,$file);
while(<$f>){chomp; push @F,$_}

## This is the rest of the oneliner above. The -pe options
## cause the file to be read and each line printed after 
## the script is applied. Since the previous block removed 
## file2 from @ARGV, this is applied to file1 only.
while (<>) {
    ## Remove the 1st item of @F. This is a line of file2.
    $k=shift(@F);

    ## Make the substitution. The \ before the " is not 
    ## needed, I just added it here because otherwise, the 
    ## syntax highlighting is broken. 
    s/(.*SRC=.)([^\"]*)/$1$k/;
    ## This print is implied by the -p flag
    print;
}

Antwort3

Der Fehler besagt, dass Ihr sed-Befehl falsch ist, nicht Ihr regulärer Ausdruck. Sie benötigen eine neue Zeile oder ein Semikolon, um den sBefehl vom folgenden {Befehl zu trennen. Entsprechend können Sie sie in separate -eArgumente einfügen.

sed -e 's/.SRC="/Repository([^"])".*/\1/p' -e '{' -e 'r Datei1' -e 'd' -e '}' Datei2

Dies führt jedoch nicht zu dem gewünschten Ergebnis. Es entfernt das Präfix …SRC="Repository/und den Teil, der mit dem nächsten Anführungszeichen beginnt, aus der Eingabe, druckt nur die Zeilen, die ersetzt wurden (aufgrund des pFlags im sBefehl und des folgenden d), und fügt File1für jede Eingabezeile (ob übereinstimmend oder nicht) eine Kopie von ein.

Wenn Sie Daten aus den beiden Dateien abgleichen möchten, benötigen Sie ein leistungsfähigeres Tool als sed¹.OhhhhoderPerlsind eine gute Wahl.

¹ Technisch gesehen ist sed Turing-vollständig, aber dies in sed zu tun wäre äußerst komplex und undurchsichtig.

verwandte Informationen