El comportamiento de las utilidades de shell difiere en formas menores entre las variantes de Unix. Hay muchas variantes de Unix , con una historia compleja . Existen esfuerzos de estandarización , como el estándar POSIX y su superconjunto, la especificación Single UNIX . Actualmente, la mayoría de los sistemas implementan POSIX: 2001, también conocida como Single UNIX Specification versión 3 , con pequeñas desviaciones y muchas extensiones. La especificación Single Unix no es un tutorial, pero la versión 3 es legible si ya tiene una idea de lo que está haciendo un comando. Puede consultarlo para saber si alguna característica es estándar o una extensión de un sistema en particular.
La mayoría de los usuarios de Unix usan Linux y no han usado ninguna otra variante. Linux viene con utilidades GNU , que a menudo tienen muchas extensiones al estándar. Por lo tanto, encontrará una gran cantidad de código que funciona en Linux pero no en otros dispositivos, ya que se basa en esas extensiones.
Con respecto a sed, consulte la especificación de Single Unix de sed para conocer el mínimo que se supone que debe admitir cada sistema, la página de manual de su sistema para saber qué admite su implementación y el manual de sed de GNU para lo que utiliza la mayoría de las personas.
Una de las extensiones no estándar en GNU sed es compatible con múltiples comandos que se ejecutan juntos. Por ejemplo, esta sed de GNU programa imprime todas las líneas que contienen una a
, pero los cambios b
en c
primer lugar:
sed -ne '/a/ {s/b/c/g; p}'
{
y en }
realidad son comandos separados, por lo que para una portabilidad total, debe especificarlos en líneas separadas (en un archivo) o en -e
argumentos separados (en la línea de comandos). La falta de un separador de comandos después {
y el uso de ;
un separador de comandos son extensiones comunes. La falta de un separador de comandos antes }
es una extensión menos común. Esto cumple con los estándares:
sed -n -e '/a/ {' -e 's/b/c/g' -e p -e '}'
Esto no es estándar pero es comúnmente aceptado:
sed -ne '/a/ { s/b/c/g; p; }'
Otra extensión no estándar pero común es el uso de \n
significar una nueva línea en un s
texto de reemplazo (el uso en una expresión regular es estándar). El método portátil es incluir la barra diagonal inversa-nueva línea en el script sed. Otra extensión común es \+
, \?
y \|
en expresiones regulares significa uno o más, como máximo uno y alternancia; Las expresiones regulares básicas portátiles no tienen ninguno de estos. Por ejemplo, el primer comando es una forma no portátil de reemplazar secuencias contiguas de espacios en blanco por una nueva línea; el segundo comando es un equivalente que cumple con los estándares.
sed -e 's/ \+/\n/'
sed -e 's/ */\
/'
sed
sí es compatible ya que hace cosas permitidas (pero no requeridas, no especificadas) por el estándar. Hay casos en los que no es compatible y dondePOSIXLY_CORRECT
puede ser útil ejecutarlo en el entorno. Al iguals/[\n]//g
que con eso, debe eliminar la reacción y losn
caracteres, pero eliminar las nuevas líneas en su lugar. O el comportamiento delN
comando en la última línea.sed -ne '/a/ { s/b/c/g; p; }'
es estándar desde la edición 2016 de la norma. Siempre fue portátil. Ver austingroupbugs.net/view.php?id=944&nbn=7OS X actualmente viene con un archivo FreeBSD de 2005. La mayoría de las diferencias a continuación también se aplican a otras versiones de BSD.
Usos sed de OS X para usos sed
-E
de ERE y GNU-r
.-E
es un alias para-r
en GNU sed (agregado en 4.2, no documentado hasta 4.3). Las versiones más recientes de FreeBSD y NetBSD son compatibles con ambos-E
y-r
. OpenBSD sed solo es compatible-E
.-i ''
funciona con OS X's sed pero no con GNU sed.-i
funciona con GNU sed, versiones recientes de NetBSD, OpenBSDsed
, pero no con OS X sed.-i -e
funciona con ambos, pero en el caso de FreeBSDsed
realiza una copia de seguridad del archivo original junto-e
con el nombre del archivo (y no necesita pasar más de una expresiónsed
).GNU interpreta sed secuencias de escape como
\t
,\n
,\001
,\x01
,\w
, y\b
. OS X's sed y POSIX sed solo interpretan\n
(pero no en la parte de reemplazo des
).GNU sed interpreta
\|
,\+
y\?
en BRE, pero sed de OS X y POSIX sed no.\(
,\)
,\{
, Y\}
son POSIX BRE.GNU sed permite omitir
;
o una nueva línea antes,}
pero sed de OS X no.i
(insert),a
(append) yc
(change) deben ir seguidos de una barra diagonal inversa y una nueva línea en OS X's sed y POSIX sed pero no en GNU sed. Sed de GNU añade una nueva línea faltante después del texto insertado pori
,a
, oc
sino OS X de sed no lo hace. Por ejemplo,sed 1ia
es una alternativa a GNUsed $'1i\\\na\n'
.Por ejemplo,
printf a|sed -n p
agrega una nueva línea en sed de OS X pero no en sed de GNU.El sistema operativo OS X no admite los modificadores
I
(sin distinción entre mayúsculas y minúsculas) oM
(multilínea). Las versiones más recientes de soporte de sed de FreeBSDI
.El sedimento de OS X no es compatible con
-s
(--separate
),-u
(--unbuffered
) o-z
(--null-data
).Una opción BSD que no es compatible con GNU sed es
-a
, lo que hace quew
anexar a un archivo en lugar de truncar un archivo.Ejemplos de comandos de sed de GNU que no funcionan con sed de OS X:
fuente
-i -e
no funciona en OSX. Se interpete-e
como el sufijo.-i
siempre requiere un sufijo, incluso si se trata de una cadena vacía. entonces-i '' -e
debería funcionar.-i -e
funciona con ambos". en su respuesta sugiere que hay una solución multiplataforma. Al parecer no hay.La mejor forma en que he encontrado que el mismo script funciona tanto en Linux como en Mac es:
fuente
perl
dónde-i
viene eso .perl -Tpi -e 's/foo/bar/' -- "$TARGET"