Ich habe eine Datei mit (vielen) Zeichenfolgen, die ich ersetzen möchte. Deshalb habe ich überlegt, einen einfachen Befehl wie diesen zu verwenden:
sed 's/string1/string2/g' file1 > out
Es sind jedoch zu viele Zeichenfolgen, um das manuell zu wiederholen. Also habe ich eine Liste aller zu ersetzenden Zeichenfolgen erstellt, jede in einer Zeile, und sie Datei A genannt. Dann habe ich eine Liste aller zu ersetzenden Zeichenfolgen erstellt und sie Datei B genannt.
Gibt es eine Möglichkeit, so etwas zu tun:
sed 's/line i of file A/line i of file B/g' file1 > out
für jede Zeile der Datei A?
Antwort1
Es wäre einfacher, eine Datei mit Eingabe- und Ersetzungszeichenfolgen in derselben Zeile zu erstellen (vorausgesetzt, weder Eingabe- noch Ersetzungszeichenfolgen enthalten Leerzeichen). Dann können Sie etwas Einfaches wie Folgendes tun:
while read n k; do sed -i "s/$n/$k/g" file1; done < fileA
BEARBEITEN:
Nachdem ich Nykakins Antwort gesehen hatte, wurde mir klar, dass Sie mit den beiden Dateien, die Sie haben, dasselbe tun können, indem Sie seinen Vorschlag mit meinem kombinieren:
paste fileA fileB | while read n k; do sed -i "s/$n/$k/g" file1; done
Antwort2
Dies ist im Grunde Ihre erste Idee, wobei die Ersetzungsbefehle jedoch in einer Datei abgelegt sind, sodass sie leichter zu handhaben sind:
tmpfile=/tmp/Asasuser.$$ exec 3<DateiA exec 4<DateiB während lesen –r astring <&3 Tun lesen –r bstring <&4 echo "s/$astring/$bstring/" >> "$tmp-Datei" Erledigt Ausführung 3<&- 4<&- sed –f "$tmpfile" Datei1 > Ausgabe rm –f "$temporäre Datei"
Dies setzt voraus, dass fileA
und fileB
die gleiche Zeilenanzahl haben (und dass diese Anzahl größer als Null ist) und dass keiner von ihnen nicht maskierte /
Zeichen enthält.
Antwort3
Wir können einfach den Befehl generieren, den wir brauchen. Nehmen wir an, die Dateien mit Listen heißen lista und listb. Dann können wir Folgendes verwenden:
$ for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done
um eine Option für sed zu generieren. Jetzt können wir sie mit eval verwenden. Nehmen wir an, unsere Datei heißt test. Wir verwenden:
$ eval "sed" $(for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done) "test"
Antwort4
paste -d : fileA fileB | sed 's/\([^:]*\):\([^:]*\)/s%\1%\2%/' > sed.script
sed -f sed.script SOURCE-FILE
SOURCE-FILE
kann entweder eine einzelne Datei oder mehrere Dateien sein. Der Text in DateiA und DateiB darf weder Doppelpunkte noch Prozentzeichen enthalten, kann aber Leerzeichen enthalten.