it-swarm.com.de

Ersetzen Sie eine Teilzeichenfolge durch eine andere Zeichenfolge im Shell-Skript

Ich habe "Ich liebe Suzi und Heiraten" und ich möchte "Suzi" in "Sara" ändern.

#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...

Das Ergebnis muss so aussehen:

firstString="I love Sara and Marry"
647
Zincode

Verwenden Sie ${parameter/pattern/string}, um das erste Auftreten eines Musters durch eine bestimmte Zeichenfolge zu ersetzen:

#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"    
# prints 'I love Sara and Marry'

Verwenden Sie zum Ersetzen aller Vorkommen ${parameter//pattern/string}:

message='The secret code is 12345'
echo "${message//[0-9]/X}"           
# prints 'The secret code is XXXXX'

(Dies ist dokumentiert in das Bash-Referenzhandbuch , §3.5.3 "Shell Parameter Expansion" .)

Beachten Sie, dass diese Funktion von POSIX nicht spezifiziert wird - es handelt sich um eine Bash-Erweiterung -, sodass sie nicht von allen Unix-Shells implementiert wird. Die entsprechende POSIX-Dokumentation finden Sie unter Die Open Group Technical Standard Base-Spezifikationen, Ausgabe 7 , Die Shell & Utilities Volume, §2.6.2 "Parameter Expansion" .

1066
ruakh

Dies kann vollständig mit der Bash-String-Manipulation erfolgen:

first="I love Suzy and Mary"
second="Sara"
first=${first/Suzy/$second}

Das wird nur das erste Vorkommen ersetzen; Um sie alle zu ersetzen, verdoppeln Sie den ersten Schrägstrich:

first="Suzy, Suzy, Suzy"
second="Sara"
first=${first//Suzy/$second}
# first is now "Sara, Sara, Sara"
168
Kevin

versuche dies:

 sed "s/Suzi/$secondString/g" <<<"$firstString"
59
Kent

Für Dash funktionieren alle vorherigen Beiträge nicht

Die POSIX sh -kompatible Lösung ist:

result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
50

Es ist besser, bash als sed zu verwenden, wenn Zeichenfolgen RegExp-Zeichen enthalten.

echo ${first_string/Suzi/$second_string}

Es ist portabel für Windows und funktioniert mit mindestens Bash 3.1.

Um zu zeigen, dass Sie sich keine großen Sorgen um die Flucht machen müssen, gehen wir wie folgt vor:

/home/name/foo/bar

Das mögen:

~/foo/bar

Aber nur wenn /home/name am Anfang ist. Wir brauchen sed nicht!

Angesichts der Tatsache, dass Bash uns magische Variablen $PWD und $HOME gibt, können wir:

echo "${PWD/#$HOME/\~}"

EDIT: Danke für Mark Haferkamp in den Kommentaren für den Hinweis zum Zitieren/Entkommen von ~. *

Beachten Sie, wie die Variable $HOME Schrägstriche enthält, die jedoch nichts zerstörten.

Weiterführende Literatur: Advanced Bash-Scripting Guide .
Wenn die Verwendung von sed ein Muss ist, vergewissern Sie sich, dass jedes Zeichen wird umgangen .

44
Camilo Martin

Wenn du morgen beschließt, dass du Marry nicht liebst, kann sie auch ersetzt werden:

today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt

Es muss 50 Wege geben, Ihren Geliebten zu verlassen.

18
Josh Habdas

Da kann ich keinen Kommentar hinzufügen. @ruaka Um das Beispiel lesbarer zu machen, schreiben Sie es so

full_string="I love Suzy and Mary"
search_string="Suzy"
replace_string="Sara"
my_string=${full_string/$search_string/$replace_string}
or
my_string=${full_string/Suzy/Sarah}
4
Nate Revo

Reine POSIX Shell-Methode, die im Gegensatz zu Roman Kazanovskyi 's sed-based answer no benötigt externe Tools, nur die eigene native der Shell Parametererweiterungen . Beachten Sie, dass lange Dateinamen minimiert werden, damit der Code besser in eine Zeile passt:

_f="I love Suzi and Marry"
s=Sara
t=Suzi
[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"
echo "$f"
_

Ausgabe:

_I love Sara and Marry
_

Wie es funktioniert:

  • Kleinstes Suffixmuster entfernen. _"${f%$t*}"_ gibt "I love" zurück, wenn das Suffix _$t_ "Suzi* "ist in _$f_" I loveSuzi and Marry ".

  • Wenn jedoch _t=Zelda_, löscht _"${f%$t*}"_ nichts und gibt die gesamte Zeichenfolge "I love Suzi and Marry" zurück.

  • Dies wird verwendet, um zu testen, ob _$t_ in _$f_ ist, wobei _[ "${f%$t*}" != "$f" ]_ als true ausgewertet wird, wenn der String _$f_ enthält "Suzi*" und false falls nicht.

  • Wenn der Test true zurückgibt, konstruieren Sie die gewünschte Zeichenfolge mit Remove Smallest Suffix Pattern _${f%$t*}_ "I love "und Kleinstes Präfixmuster entfernen _${f#*$t}_" and Marry ", mit der 2. Zeichenfolge _$s_" Sara "dazwischen.

1
agc