Tengo "Amo a Suzi y me caso" y quiero cambiar "Suzi" a "Sara".
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
El resultado debe ser así:
firstString="I love Sara and Marry"
Tengo "Amo a Suzi y me caso" y quiero cambiar "Suzi" a "Sara".
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
El resultado debe ser así:
firstString="I love Sara and Marry"
Respuestas:
Para reemplazar la primera aparición de un patrón con una cadena dada, use :${parameter/pattern/string}
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"
# prints 'I love Sara and Marry'
Para reemplazar todas las ocurrencias, use :${parameter//pattern/string}
message='The secret code is 12345'
echo "${message//[0-9]/X}"
# prints 'The secret code is XXXXX'
(Esto está documentado en el Manual de referencia de Bash , §3.5.3 "Expansión de parámetros de shell" ).
Tenga en cuenta que POSIX no especifica esta característica, es una extensión Bash, por lo que no todos los shells de Unix la implementan. Para obtener la documentación relevante de POSIX, consulte las especificaciones básicas de la norma técnica de Open Group, número 7 , el volumen Shell y utilidades , §2.6.2 "Expansión de parámetros" .
\n
en ese contexto se representaría a sí mismo, no a una nueva línea. No tengo Bash útil en este momento para la prueba, pero usted debe ser capaz de escribir algo como: $STRING="${STRING/$'\n'/<br />}"
. (Aunque probablemente quieras STRING//
- reemplazar todo - en lugar de solo STRING/
)
echo ${my string foo/foo/bar}
. Necesitaríasinput="my string foo"; echo ${input/foo/bar}
//
directamente, menciona lo que sucede "Si el patrón comienza con ' /
'" (lo cual ni siquiera es exacto, ya que el resto de esa oración supone que el extra /
no es realmente parte de el patrón), pero no conozco ninguna fuente mejor.
Esto se puede hacer completamente con la manipulación de cadenas bash:
first="I love Suzy and Mary"
second="Sara"
first=${first/Suzy/$second}
Eso reemplazará solo la primera ocurrencia; para reemplazarlos a todos, doble la primera barra:
first="Suzy, Suzy, Suzy"
second="Sara"
first=${first//Suzy/$second}
# first is now "Sara, Sara, Sara"
Para Dash, todas las publicaciones anteriores no funcionan
La sh
solución compatible con POSIX es:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
result=$(echo $firstString | sed "s/Suzi/$secondString/g")
echo
argumento. Funciona engañosamente sin citar con cadenas simples, pero se rompe fácilmente en cualquier cadena de entrada no trivial (espaciado irregular, metacaracteres de shell, etc.).
prueba esto:
sed "s/Suzi/$secondString/g" <<<"$firstString"
Es mejor usar bash que sed
si las cadenas tienen caracteres RegExp.
echo ${first_string/Suzi/$second_string}
Es portátil para Windows y funciona con al menos tan antiguo como Bash 3.1.
Para mostrar que no necesita preocuparse demasiado por escapar, cambiemos esto:
/home/name/foo/bar
Dentro de esto:
~/foo/bar
Pero solo si /home/name
es al principio. No necesitamos sed
!
Dado que bash nos da variables mágicas $PWD
y $HOME
podemos:
echo "${PWD/#$HOME/\~}"
EDITAR: Gracias por Mark Haferkamp en los comentarios por la nota sobre citas / escape ~
. *
Observe cómo la variable $HOME
contiene barras diagonales, pero esto no rompió nada.
Lectura adicional: Guía avanzada de secuencias de comandos Bash .
Si usar sed
es imprescindible, asegúrate de escapar de todos los personajes .
sed
el pwd
comando para evitar definir una nueva variable cada vez que se $PS1
ejecuta mi personalizado . ¿Bash proporciona una forma más general que las variables mágicas para usar la salida de un comando para el reemplazo de cadenas? En cuanto a su código, tuve que escapar ~
para evitar que Bash lo expandiera a $ HOME. Además, ¿qué hace el #
comando?
~
": observe cómo cité cosas. ¡Recuerda siempre citar cosas! Y esto no solo funciona para las variables mágicas: cualquier variable es capaz de sustituciones, obtener longitud de cadena y más, dentro de bash. Felicidades por intentar tu $PS1
ayuno: también te puede interesar $PROMPT_COMMAND
si estás más cómodo con otro lenguaje de programación y quieres codificar un mensaje compilado.
echo "${PWD/#$HOME/~}"
no reemplaza mi $HOME
con ~
. Reemplazar ~
con \~
o '~'
funciona. Cualquiera de estos funciona en Bash 4.2.53 en otra distribución. ¿Puedes actualizar tu publicación para cotizar o escapar ~
para una mejor compatibilidad? Lo que quise decir con mi pregunta de "variables mágicas" fue: ¿Puedo usar la sustitución de variables de Bash en, por ejemplo, la salida de uname
sin guardarla primero como una variable? En cuanto a mi personal $PROMPT_COMMAND
, es complicado .
Si mañana decides que no amas a Marry, ella también puede ser reemplazada:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
Debe haber 50 formas de dejar a tu amante.
Como no puedo agregar un comentario. @ruaka Para que el ejemplo sea más legible, escríbalo así
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}
Pura POSIX método de cáscara, que a diferencia de Romano Kazanovskyi 's sed
respuesta basada no necesita herramientas externas, sólo propios nativos de la concha Expansiones de parámetros . Tenga en cuenta que los nombres largos de archivo se minimizan para que el código se ajuste mejor en una línea:
f="I love Suzi and Marry"
s=Sara
t=Suzi
[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"
echo "$f"
Salida:
I love Sara and Marry
Cómo funciona:
Eliminar el patrón de sufijo más pequeño. "${f%$t*}"
devuelve " I love
" si el sufijo $t
" Suzi*
" está en $f
" ". I love
Suzi and Marry
Pero si t=Zelda
, entonces "${f%$t*}"
no elimina nada y devuelve toda la cadena " I love Suzi and Marry
".
Esto se utiliza para probar si $t
está dentro $f
de lo [ "${f%$t*}" != "$f" ]
cual se evaluará como verdadero si la $f
cadena contiene " Suzi*
" y falso si no.
Si la prueba devuelve verdadero , construya la cadena deseada usando Eliminar patrón de sufijo más pequeño ${f%$t*}
" I love
" y Eliminar patrón de prefijo más pequeño ${f#*$t}
" and Marry
", con la segunda cadena $s
" Sara
" en el medio.
Sé que esto es viejo, pero como nadie mencionó el uso de awk:
firstString="I love Suzi and Marry"
echo $firstString | awk '{gsub("Suzi","Sara"); print}'
echo [string] | sed "s/[original]/[target]/g"