Ich versuche, die in Datei1 gefundenen Zeichenfolgen durch Zeichenfolgen in Datei2 zu ersetzen
Datei1
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2011/03/27&EntityID=Ad12911&imgExtension=" />
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2011/03/20&EntityID=Ad13304&imgExtension=" />
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2010/08/29&EntityID=Ad13724&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, File1
alles 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 -i
bewirkt 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 s
Befehl vom folgenden {
Befehl zu trennen. Entsprechend können Sie sie in separate -e
Argumente 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 p
Flags im s
Befehl und des folgenden d
), und fügt File1
fü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.