
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 echo
die Variablen einstelle, erhalte ich innerhalb der Schleife die richtigen Zeichenfolgen. Wenn im Befehl explizit zwei Zeichenfolgen festgelegt sind, sed
funktioniert 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 sed
Skript, das alle Ersetzungen vornimmt, und wenden Sie dieses sed
Skript 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 OLD
wird NEW
das sed
Skript 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 -i
Flag 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).