Bash while-Schleife suchen und ersetzen mit sed

Bash while-Schleife suchen und ersetzen mit sed

Ich habe ein Problem mit meinem folgenden Skript (das ist der relevante Teil davon):

#!/bin/bash

OLD=(
"_MAIN1_"
"_MAIN2_"
)

NEW=(
"#111"
"#222"
)

length=${#OLD[*]}

i=0

while (( i < length ))
do
  sed -e "s/${OLD[$i]}/${NEW[$i]}/g" oldfile.txt > newfile.txt

  #sed -e 's/_MAIN1_/#111/g' oldfile.txt > newfile.txt  # this works

  # Another way that does not work
  #sed -e 's/'"${OLD[$i]}"'/'"${NEW[$i]}"'/g' oldfile.txt > newfile.txt

  ((i++))
done

exit 0

Mein Ziel ist es, Zeichenfolgen in einer Datei zu ersetzen und in einer neuen zu speichern. Die „alten“ und „neuen“ Zeichenfolgen werden in einem Array gespeichert.

Ich habe vieles ausprobiert und mit einfachen und doppelten Anführungszeichen herumgespielt – aber nichts hat funktioniert. Wenn ich echodie Variablen einstelle, erhalte ich innerhalb der Schleife die richtigen Zeichenfolgen. Wenn im Befehl explizit zwei Zeichenfolgen festgelegt sind, sedfunktioniert es hierfür einwandfrei.

Die Zeichenfolgenmuster folgen denen in meinen Beispiel-Arrays („neu“ enthält den Unterstrich „_“ und „alt“ enthält das Hashtag „#“).

Ich führe Bash auf einer Ubuntu 16.04-Box aus.

Vielen Dank!

Antwort1

Erstellen Sie ein sedSkript, das alle Ersetzungen vornimmt, und wenden Sie dieses sedSkript dann auf Ihre Datei an.

for (( i=0; i<${#OLD[@]}; ++i )); do
        printf 's/%s/%s/g\n' "${OLD[$i]}" "${NEW[$i]}"
done >script.sed

sed -f script.sed inputfile >outputfile && mv outptufile inputfile && rm script.sed

Auf diese Weise begrenzen Sie die Anzahl der erforderlichen Analysen der Eingabedatei auf einmal.

Für die angegebenen Daten OLDwird NEWdas sedSkript wie folgt generiert:

s/_MAIN1_/#111/g
s/_MAIN2_/#222/g

Antwort2

Ihr gesamtes Skript (das nicht funktioniert) kann durch die folgende einzelne Zeile ersetzt werden:

sed 's/_MAIN\([12]\)_/#\1\1\1/g' oldfile.txt > newfile.txt

Oder lesbarer, aber gleichwertig:

sed 's/_MAIN1_/#111/g;s/_MAIN2_/#222/g' oldfile.txt > newfile.txt

Es gibt mehrere Dutzend andere Möglichkeiten, dies zu erreichen, abhängig von IhrertatsächlichAnwendungsfall (z. B. woher die Daten kommen, wie die Werte tatsächlich aussehen, was Sie mit den Daten tun möchten usw.).

Antwort3

Dank anRakesh SharmaKommentar von: Ich könnte das Problem lösen, indem ich das -iFlag im sed-Befehl verwende. Vor der Schleife wird die Originaldatei gesichert:

cp oldfile.txt oldfile.backup
while (( i < length ))
do
  sed -i -e 's/'"${OLD[$i]}"'/'"${NEW[$i]}"'/g' oldfile.txt
  ((i++))
done

Das nächste Mal werde ich Perl für String-Manipulationen verwenden.

Bearbeiten:Hinzugefügt ((i++)), um eine Endlosschleife zu verhindern (Danke anKusalananda's Kommentar).

verwandte Informationen