Vraag Vervang een subtekenreeks voor een andere reeks in het shellscript


Ik heb "I love Suzi and Marry" en ik wil "Suzi" in "Sara" veranderen.

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

Het resultaat moet zo zijn:

firstString="I love Sara and Marry"

438
2017-11-03 16:01


oorsprong


antwoorden:


Om de te vervangen eerste optreden van een patroon met een gegeven tekenreeks, gebruik ${parameter/patroon/draad}:

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

Vervangen alle voorvallen, gebruik ${parameter//patroon/draad}:

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

(Dit is gedocumenteerd in de Bash Reference Manual, §3.5.3 "Shell parameteruitbreiding".)

Merk op dat deze functie niet wordt gespecificeerd door POSIX - het is een Bash-extensie - dus niet alle Unix-shells implementeren het. Raadpleeg voor de relevante POSIX-documentatie De standaardspecificaties van de Open Group technische norm, uitgave 7, de Shell & Utilities volume, §2.6.2 "Parameteruitbreiding".


726
2017-11-03 16:05



Dit kan volledig worden gedaan met bash-string manipulatie:

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

Dat zal alleen de eerste keer voorkomen; om ze allemaal te vervangen, verdubbel je de eerste schuine streep:

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

128
2017-11-03 16:05



probeer dit:

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

45
2017-11-03 16:04



Het is beter om bash te gebruiken dan sed als strings RegExp-tekens hebben.

echo ${first_string/Suzi/$second_string}

Het is draagbaar voor Windows en werkt met minstens zo oud als Bash 3.1.

Laten we het volgende zien om te laten zien dat je je niet al te veel zorgen hoeft te maken over het ontsnappen:

/home/name/foo/bar

In dit:

~/foo/bar

Maar alleen als /home/name is in het begin. We hebben het niet nodig sed!

Gegeven dat bash ons magische variabelen geeft $PWD en $HOME, we kunnen:

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

BEWERK: Bedankt voor Mark Haferkamp in de opmerkingen voor de opmerking over citeren / ontsnappen ~. *

Merk op hoe de variabele $HOME bevat slashes maar dit brak niets.

Verder lezen: Geavanceerde Bash-Scripting Guide.
Als u gebruikt sed is een must, wees zeker van ontsnappen aan elk karakter.


38
2018-06-22 03:43



Voor Dash werken niet alle vorige berichten

De POSIX sh compatibele oplossing is:

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

25
2018-04-09 08:56



Als je morgen besluit dat je niet van Marry houdt, kan ze ook worden vervangen:

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

Er moeten 50 manieren zijn om je geliefde te verlaten.


7
2017-07-11 02:39