¿Existe una invocación de sededición in situ sin copias de seguridad que funcione tanto en Linux como en Mac? Si bien el BSD sedenviado con OS X parece necesitar sed -i '' …, las seddistribuciones GNU Linux generalmente vienen con interpreta las comillas como un nombre de archivo de entrada vacío (en lugar de la extensión de copia de seguridad), y necesita en su sed -i …lugar.
¿Existe alguna sintaxis de línea de comando que funcione con ambos tipos, por lo que puedo usar el mismo script en ambos sistemas?

Respuestas:
Si realmente quiere usar
sed -ila forma 'fácil', lo siguiente FUNCIONA tanto en GNU como en BSD / Macsed:Tenga en cuenta la falta de espacio y el punto.
Prueba:
Obviamente, podría simplemente eliminar los
.bakarchivos.fuente
sed)sedno acepta una posicióncommandargumento cuando se invoca con-i- que debe ser suministrado con otra bandera,-e. Por lo tanto, el comando se convierte en:sed -i.bak -e 's/foo/bar/' filenamesed -i.bak 's/foo/bar/' file && rm file.bakEsto funciona con GNU sed, pero no en OS X:
Esto funciona en OS X, pero no con GNU sed:
En OS X usted
sed -i -eya que la extensión del archivo de respaldo se establecería en-esed -i'' -epor las mismas razones: necesita un espacio entre-iy''.fuente
-iy-i''son idénticos en el tiempo de análisis de shell;sedno puede comportarse de manera diferente en esas dos primeras invocaciones, porque obtiene exactamente los mismos argumentos.Cuando estoy en OSX, siempre instalo la versión de GNU sed a través de Homebrew, para evitar problemas en los scripts, porque la mayoría de los scripts fueron escritos para versiones de GNU sed.
Entonces su BSD sed será reemplazado por GNU sed.
Alternativamente, puede instalar sin nombres predeterminados, pero luego:
PATHcomo se indica después de instalargnu-sedgsedoseddependiendo de su sistemafuente
--with-default-namesfue retirado de homebrew núcleos , más información en esta respuesta. al instalargnu-sedahora, las instrucciones de instalación especifican que necesita agregargnubina suPATH:PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"Como Noufal Ibrahim pregunta, ¿por qué no puedes usar Perl? Cualquier Mac tendrá Perl, y hay muy pocas distribuciones de Linux o BSD que no incluyan alguna versión de Perl en el sistema base. Uno de los únicos entornos que podrían carecer de Perl sería BusyBox (que funciona como GNU / Linux para
-i, excepto que no se puede especificar una extensión de copia de seguridad).Como recomienda ismail ,
y esto parece una mejor solución en casi cualquier caso que los scripts, los alias u otras soluciones para tratar la incompatibilidad fundamental
sed -ientre GNU / Linux y BSD / Mac.fuente
perles parte de la especificación de Linux Standard Base desde el 1 de mayo de 2009. refspecs.linuxfoundation.org/LSB_4.0.0/LSB-Languages/…No hay forma de que funcione.
Una forma es usar un archivo temporal como:
Esto funciona en ambos
fuente
Respuesta: No.
La respuesta originalmente aceptada en realidad no hace lo que se solicita (como se señala en los comentarios). (Encontré esta respuesta cuando busqué la razón por la que
file-eaparecía "al azar" en mis directorios).Aparentemente no hay forma de
sed -itrabajar de manera consistente tanto en MacOS como en Linuces.Mi recomendación, por lo que vale, no es actualizar en el lugar
sed(que tiene modos de falla complejos), sino generar nuevos archivos y cambiarles el nombre después. En otras palabras: evitar-i.fuente
La
-iopción no es parte de POSIX Sed . Un método más portátil sería usar Vim en modo Ex:%seleccione todas las líneassreemplazarxguardar y cerrarfuente
Aquí hay otra versión que funciona en Linux y macOS sin usar
evaly sin tener que eliminar archivos de copia de seguridad. Utiliza matrices Bash para almacenar lossedparámetros, que es más limpio que usareval:Esto no crea un archivo de copia de seguridad, ni un archivo con citas adjuntas.
fuente
sedi=(-i) && [ "$(uname)" == "Darwin" ] && sedi=(-i '')sed "${sedi[@]}" -e 's/foo/bar/' target.fileLa respuesta de Steve Powell es bastante correcta, al consultar la página MAN para sed en OSX y Linux (Ubuntu 12.04) destaca la incompatibilidad dentro del uso de sed 'in situ' en los dos sistemas operativos.
JFYI, no debería haber espacio entre el -i y las comillas (que denotan una extensión de archivo vacía) usando la versión Linux de sed, por lo tanto
sed Linux Man Page
y
Página de manual de sed OSX
Lo resolví en un script usando un comando alias'd y la salida del nombre del sistema operativo de ' uname ' dentro de un bash 'if'. Intentar almacenar cadenas de comandos dependientes del sistema operativo en variables fue impredecible al interpretar las comillas. El uso de ' shopt -s expand_aliases ' es necesario para expandir / usar los alias definidos en su script. El uso de shopt se trata aquí .
fuente
Si necesita hacer
sedin situ en unbashscript, y NO desea que el lugar resulte con archivos .bkp, y tiene una manera de detectar el sistema operativo (por ejemplo, usando ostype.sh ), - entonces El siguiente truco con elbashshell incorporadoevaldebería funcionar:fuente
Puedes usar esponja. Sponge es un antiguo programa de Unix, que se encuentra en el paquete moreutils (tanto en ubuntu y probablemente debian, como en homebrew en mac).
Almacenará todo el contenido de la tubería, esperará hasta que la tubería esté cerrada (probablemente significa que el archivo de entrada ya está cerrado) y luego sobrescribirá:
Desde la página del manual :
fuente
Lo siguiente funciona para mí en Linux y OS X:
sed -i' ' <expr> <file>por ejemplo, para un archivo que
fcontieneaaabbaabased -i' ' 's/b/c/g' fcede
aaaccaacatanto en Linux como en Mac. Tenga en cuenta que hay una cadena entre comillas que contiene un espacio , sin espacio entre-iy la cadena. Las comillas simples o dobles funcionan.En Linux estoy usando la
bashversión 4.3.11 bajo Ubuntu 14.04.4 y en la versión Mac 3.2.57 bajo OS X 10.11.4 El Capitan (Darwin 15.4.0).fuente
Me encontré con este problema. La única solución rápida fue reemplazar el sed en mac a la versión gnu:
fuente