Ho "Adoro Suzi e Marry" e voglio cambiare "Suzi" in "Sara".
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
Il risultato deve essere così:
firstString="I love Sara and Marry"
Ho "Adoro Suzi e Marry" e voglio cambiare "Suzi" in "Sara".
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
Il risultato deve essere così:
firstString="I love Sara and Marry"
Risposte:
Per sostituire la prima occorrenza di un modello con una determinata stringa, utilizzare :${parameter/pattern/string}
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"
# prints 'I love Sara and Marry'
Per sostituire tutte le occorrenze, utilizzare :${parameter//pattern/string}
message='The secret code is 12345'
echo "${message//[0-9]/X}"
# prints 'The secret code is XXXXX'
(Questo è documentato nel l' Bash Reference Manual , §3.5.3 "Shell parametri di espansione" .)
Nota che questa funzione non è specificata da POSIX - è un'estensione Bash - quindi non tutte le shell Unix la implementano. Per la documentazione POSIX pertinente, consultare Le specifiche di base dello standard tecnico Open Group, Numero 7 , il volume Shell & Utilities , §2.6.2 "Espansione dei parametri" .
\n
in quel contesto rappresenterebbe se stesso, non una nuova riga. Non ho Bash a portata di mano in questo momento di prova, ma si dovrebbe essere in grado di scrivere qualcosa di simile, $STRING="${STRING/$'\n'/<br />}"
. (Anche se probabilmente vuoi STRING//
- sostituisci tutto - invece di solo STRING/
.)
echo ${my string foo/foo/bar}
. Avresti bisognoinput="my string foo"; echo ${input/foo/bar}
//
direttamente, menziona cosa succede "Se il modello inizia con ' /
'" (che non è nemmeno accurato, poiché il resto di quella frase presuppone che il extra /
non sia effettivamente parte di lo schema) - ma non conosco alcuna fonte migliore.
Questo può essere fatto interamente con la manipolazione della stringa bash:
first="I love Suzy and Mary"
second="Sara"
first=${first/Suzy/$second}
Ciò sostituirà solo la prima occorrenza; per sostituirli tutti, raddoppia la prima barra:
first="Suzy, Suzy, Suzy"
second="Sara"
first=${first//Suzy/$second}
# first is now "Sara, Sara, Sara"
Per Dash tutti i post precedenti non funzionano
La sh
soluzione compatibile POSIX è:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
result=$(echo $firstString | sed "s/Suzi/$secondString/g")
echo
all'argomento. Funziona ingannevolmente senza virgolette con stringhe semplici, ma si rompe facilmente su qualsiasi stringa di input non banale (spaziatura irregolare, metacaratteri shell, ecc.).
prova questo:
sed "s/Suzi/$secondString/g" <<<"$firstString"
È meglio usare bash che sed
se le stringhe hanno caratteri RegExp.
echo ${first_string/Suzi/$second_string}
È portatile per Windows e funziona con almeno almeno Bash 3.1.
Per mostrare che non devi preoccuparti molto dell'evasione, cambiamo questo:
/home/name/foo/bar
In questo:
~/foo/bar
Ma solo se /home/name
è all'inizio. Non abbiamo bisogno sed
!
Dato che bash ci fornisce variabili magiche $PWD
e $HOME
possiamo:
echo "${PWD/#$HOME/\~}"
EDIT: Grazie per Mark Haferkamp nei commenti per la nota sulla citazione / fuga ~
. *
Nota come la variabile $HOME
contiene barre, ma ciò non ha interrotto nulla.
Ulteriori letture: Guida avanzata agli script di Bash .
Se l'utilizzo sed
è obbligatorio, assicurati di sfuggire a tutti i personaggi .
sed
il pwd
comando per evitare di definire una nuova variabile ogni volta che la mia $PS1
esecuzione personalizzata . Bash fornisce un modo più generale delle variabili magiche per utilizzare l'output di un comando per la sostituzione di stringhe? Per quanto riguarda il tuo codice, ho dovuto sfuggire a ~
per evitare che Bash lo espandesse in $ HOME. Inoltre, cosa fa il #
comando al comando?
~
": nota come ho citato cose. Ricorda di citare sempre cose! E questo non funziona solo per le variabili magiche: qualsiasi variabile è in grado di sostituire, ottenere la lunghezza della stringa e altro, entro bash. Congratulazioni per aver provato al tuo $PS1
digiuno: potresti anche essere interessato a $PROMPT_COMMAND
se ti senti più a tuo agio in un altro linguaggio di programmazione e vuoi codificare un prompt compilato.
echo "${PWD/#$HOME/~}"
non sostituisco il mio $HOME
con ~
. Sostituzione ~
con \~
o '~'
funziona. Ognuno di questi lavori su Bash 4.2.53 su un'altra distro. Puoi aggiornare il tuo post per citare o scappare ~
per una migliore compatibilità? Quello che intendevo con la mia domanda sulle "variabili magiche" era: posso usare la sostituzione delle variabili di Bash, ad esempio, sull'output uname
senza prima salvarlo come variabile? Per quanto riguarda il mio personale $PROMPT_COMMAND
, è complicato .
Se domani decidi di non amare Marry, anche lei può essere sostituita:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
Ci devono essere 50 modi per lasciare il tuo amante.
Dal momento che non posso aggiungere un commento. @ruaka Per rendere l'esempio più leggibile scrivilo in questo modo
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}
Pure POSIX metodo di conchiglia, che a differenza di Romano Kazanovskyi 's sed
risposta basata su non ha bisogno di strumenti esterni, a pochi propri nativi della shell espansioni di parametri . Si noti che i nomi di file lunghi sono ridotti a icona in modo che il codice si adatti meglio su una riga:
f="I love Suzi and Marry"
s=Sara
t=Suzi
[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"
echo "$f"
Produzione:
I love Sara and Marry
Come funziona:
Rimuovi il modello di suffisso più piccolo. "${f%$t*}"
restituisce " I love
" se il suffisso $t
" Suzi*
" è in $f
" ". I love
Suzi and Marry
Ma if t=Zelda
, quindi "${f%$t*}"
non elimina nulla e restituisce l'intera stringa " I love Suzi and Marry
".
Questo è usato per verificare se $t
è dentro $f
con [ "${f%$t*}" != "$f" ]
cui valuterà vero se la $f
stringa contiene " Suzi*
" e falso in caso contrario.
Se il test restituisce true , costruisci la stringa desiderata utilizzando Rimuovi modello suffisso più piccolo ${f%$t*}
" I love
" e Rimuovi modello prefisso più piccolo ${f#*$t}
" and Marry
", con la seconda stringa $s
" Sara
" in mezzo.
So che questo è vecchio ma dal momento che nessuno ha menzionato l'uso di awk:
firstString="I love Suzi and Marry"
echo $firstString | awk '{gsub("Suzi","Sara"); print}'
echo [string] | sed "s/[original]/[target]/g"