Tenía la impresión de queEspecificaciones POSIX parased
que es necesario alinear a la izquierda el texto en la línea que sigue al i\
comando, a menos que desee espacios en blanco al principio en la salida.
Una prueba rápida en mi Mac (usando BSD sed) muestra que tal vez esto seanonecesario:
$ cat test.sed
#!/bin/sed -f
i\
This line starts with spaces.
$ echo some text | sed -f test.sed
This line starts with spaces.
some text
$
Sin embargo, parece que no puedo encontrar esto documentado en ninguna parte. No está en las especificaciones POSIX y ni siquiera está en sed
la página de manual de mi sistema.
¿Puedo confiar en este comportamiento en sed
scripts que quiero que sean portátiles? ¿Qué tan portátil es?
(¿Está documentado?¿en cualquier lugar?)
(Pregunta adicional: ¿Es posible forzar sed
la inserción de espacios en blanco al comienzo de una línea fija pasada a i\
?)
Respuesta1
No, pero su secuencia de comandos será portátil siempre que escape de cualquier espacio en blanco inicial. Por qué ? Porque algunos sed
anuncios eliminan los caracteres en blanco de las líneas de texto y la única forma de evitarlo es escapar del espacio en blanco inicial, como explican estas páginas de manual que datan del siglo pasado:1,2,3
Lo mismo ocurre BSD
sed
( OSX
simplemente copié el código, no es su extensión) y si revisa los archivos y lee elman
página deBSD 2.11
está bastante claro:
(1)yo\
texto
.......
Un argumento denotadotextoconsta de una o más líneas, todas menos la última terminan con'\'
para ocultar la nueva línea. Las barras invertidas en el texto se tratan como barras invertidas en la cadena de reemplazo de un's'
comando y pueden usarse para proteger los espacios en blanco y tabulaciones iniciales contra la eliminación que se realiza en cada línea de script.
Ahora bien, ¿dónde está documentado esto en la especificación POSIX? solo dice
El texto del argumento constará de una o más líneas. Cada <nueva línea> incrustada en el texto deberá estar precedida por una <barra invertida>. Se eliminarán otros caracteres <barra invertida> del texto y el siguiente carácter se tratará literalmente.
y si te desplazas hacia abajoRAZÓN FUNDAMENTALdice
Los requisitos para la aceptación de caracteres <en blanco> y <espacio> en las líneas de comando se han hecho más explícitos que en las primeras propuestas para describir claramente la práctica histórica y eliminar la confusión sobre la frase "proteger los espacios en blanco iniciales [sic] y las pestañas de la eliminación". eso se hace en cada línea de script" que aparece en gran parte de la documentación histórica de la descripción del texto de la utilidad sed. (No todas las implementaciones han eliminado los caracteres <en blanco> de las líneas de texto, aunque todas han permitido caracteres <en blanco> iniciales que preceden a la dirección en una línea de comando).
Desde la parte con"Se pueden utilizar barras invertidas para"no estaba incluida en esa cita, la frase restante"proteger los espacios en blanco iniciales..."no tiene ningún sentido... 1
De todos modos, para resumir: algunas implementaciones eliminaron (y algunas todavía lo hacen) los espacios en blanco de las líneas de texto. Sin embargo, dado que la especificación POSIX que deben cumplir todas las implementaciones dice
Se eliminarán otros caracteres <barra invertida> del texto y el siguiente carácter se tratará literalmente.
Podemos concluir que la forma portátil de sangrar las líneas en el texto que se va a insertar es escapando del espacio en blanco inicial en cada una de esas líneas.
1: Tampoco entiendo por qué OSX
la BSD
gente ha cambiado todo el párrafo de la man
página sin alterar el código fuente; obtienes el mismo comportamiento que antes, pero la sección man que documenta estas cosas ya no está ahí.
Respuesta2
Es sed
una extensión de OSX, no un comportamiento estándar. Puedes vereste enlace, en funcióncompile_text
:
/*
* Compile the text following an a or i command.
*/
static char *
compile_text()
{
int asize, size;
char *text, *p, *op, *s;
char lbuf[_POSIX2_LINE_MAX + 1];
asize = 2 * _POSIX2_LINE_MAX + 1;
text = xmalloc(asize);
size = 0;
while (cu_fgets(lbuf, sizeof(lbuf))) {
op = s = text + size;
p = lbuf;
EATSPACE();
for (; *p; p++) {
if (*p == '\\')
p++;
*s++ = *p;
}
size
Se comieron espacios usando EATSPACE
macro.
En FreeBSD sed
, que puede tratar incorrectamente \
caracteres de continuación de línea cuando se usa ,,, a
el comportamiento es más extraño. En mi FreeBSD 9.3:i
c
$ echo 1 | sed -e 'i\ 1'
": extra characters after \ at the end of i command
pero:
$ echo 1 | sed -e 'i\
2'
2
1
Funciona y también come espacios.
GNU sed
, la reliquia familiar, sed
no tiene este problema.
Respuesta3
Cuonglmdio la mejor respuesta, pero para que conste esto es lo queÑU sed
hace:
echo foo | sed 'i\
This line starts with spaces.'
Producción:
This line starts with spaces.
foo