El comando sed con la opción -i falla en Mac, pero funciona en Linux

Resuelto Yarin asked hace 14 años • 13 respuestas

Utilicé con éxito el siguiente sedcomando para buscar/reemplazar texto en Linux:

sed -i 's/old_link/new_link/g' *

Sin embargo, cuando lo pruebo en mi Mac OS X, aparece:

"el comando c espera \ seguido de texto"

Pensé que mi Mac ejecuta un shell BASH normal. ¿Qué pasa?

EDITAR:

Según @High Performance, esto se debe a que Mac sedtiene un sabor diferente (BSD), por lo que mi pregunta sería ¿cómo puedo replicar este comando en BSD sed?

EDITAR:

Aquí hay un ejemplo real que causa esto:

sed -i 's/hello/gbye/g' *
Yarin avatar Nov 22 '10 22:11 Yarin
Aceptado

La -iopción (alternativamente --in-place) significa que desea que los archivos se editen en el lugar, en lugar de transmitir el cambio a un nuevo lugar.

La modificación de un archivo in situ sugiere la necesidad de un archivo de copia de seguridad, por lo que se espera una extensión especificada por el usuario después de -i, pero el análisis del argumento de extensión se maneja de manera diferente en GNU sed y Mac (BSD) sed:

  • GNU : "Si no se proporciona ninguna extensión, el archivo original se sobrescribe sin realizar una copia de seguridad". - efectivamente, puedes omitir especificar una extensión de archivo por completo. La extensión debe suministrarse inmediatamente después del-i, sin espacio intermedio.
  • Mac (BSD) : "Si se proporciona una extensión de longitud cero, no se guardará ninguna copia de seguridad". - debe proporcionar una extensión, pero puede ser la cadena vacía '' si lo desea, para deshabilitar la copia de seguridad.

Entonces GNU y Mac interpretarán esto de manera diferente:

sed -i 's/hello/bye/g' jkl.txt
  • GNU : no se proporciona ninguna extensión inmediatamente después de -i, así que no cree ninguna copia de seguridad, utilícela s/hello/bye/gcomo comando de edición de texto y actúe sobre el archivo jkl.txtin situ.
  • Mac (BSD) : Se utiliza s/hello/bye/gla extensión del archivo de copia de seguridad (!), se utiliza jkl.txtcomo comando de edición de texto, pero ¡oh, oh!: el código de comando proporcionado allí es j(no, por ejemplo s, un código de comando válido para sustitución), por lo que se produce un error. con invalid command code j.

Solución portátil

Para obtener un comando portátil, puede utilizar esta invocación, que funciona tanto en GNU sed como en Mac (BSD) seden Mac OS X Mavericks (v10.9, lanzado en junio de 2013) y versiones posteriores:

sed -i'' -e 's/hello/bye/g' jkl.txt

Colocar la extensión inmediatamente después de -i(por ejemplo , -i''o -i'.bak', sin un espacio) es lo que sedespera GNU, y ahora Mac (BSD) también lo acepta sed, aunque no fue tolerado por versiones anteriores (por ejemplo, con Mac OS X v10.6, un se requería espacio después de -i, por ejemplo -i '.bak').

El -eparámetro nos permite ser explícitos sobre dónde declaramos el comando de edición.

Hasta que se actualizó Mac OS en 2013, no había ningún comando portátil entre GNU y Mac (BSD), ya que estas variantes también fallaban:

  • sed -i -e ...- no funciona en OS X ya que crea -ecopias de seguridad
  • sed -i '' -e ...- falla en GNU

Cuando no había un sedcomando funcionando en todas las plataformas, podría haber intentado usar otro comando para lograr el mismo resultado, por ejemplo perl -i -pe's/old_link/new_link/g' *.

Sinetris avatar Nov 22 '2010 15:11 Sinetris

Creo que en OS X cuando usas -i se requiere una extensión para los archivos de respaldo . Intentar:

sed -i .bak 's/hello/gbye/g' *

Usando GNU sedla extensión es opcional .

Dennis Williamson avatar Nov 22 '2010 15:11 Dennis Williamson

Esto funciona con las versiones GNU y BSD de sed:

sed -i'' -e 's/old_link/new_link/g' *

o con respaldo:

sed -i'.bak' -e 's/old_link/new_link/g' *

¡ Tenga en cuenta que falta espacio después de -ila opción! (Necesario para GNU sed)

chipiik avatar Feb 11 '2013 13:02 chipiik

Tuve el mismo problema en Mac y lo resolvió con brew:

brew install gnu-sed

y utilizar como

gsed SED_COMMAND

También puede establecer sedcomo alias gsed(si lo desea):

alias sed=gsed
Sruthi Poddutur avatar Jan 01 '2017 15:01 Sruthi Poddutur