So ersetzen Sie eine Liste von Zeichenfolgen durch eine andere Liste

So ersetzen Sie eine Liste von Zeichenfolgen durch eine andere Liste

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 fileAund fileBdie 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-FILEkann entweder eine einzelne Datei oder mehrere Dateien sein. Der Text in DateiA und DateiB darf weder Doppelpunkte noch Prozentzeichen enthalten, kann aber Leerzeichen enthalten.

verwandte Informationen