Usando un documento aquí para `sed` y un archivo


10

Quiero usar un documento here-doc para comandos sed y proporcionar el archivo que se leerá y el archivo de salida.

He visto Here-Documents de la guía Advanced Bash Scripting, pero no menciona nada sobre argumentos regulares al usar un here-doc. ¿Es posible?

Me gustaría lograr algo como lo siguiente:

#!/bin/bash
OUT=/tmp/outfile.txt
IN=/my_in_file.txt

sed $IN << SED_SCRIPT
    s/a/1/g
    s/test/full/g

SED_SCRIPT 
> $OUT;

Cualquier ayuda es muy apreciada.

Respuestas:


14

Puede decirle a GNU sed que lea el script desde una entrada estándar -f -, -flo que significa leer el script desde un archivo y -significa entrada estándar como es común con muchos comandos.

sed -f - "$IN" > "$OUT" << SED_SCRIPT
    s/a/1/g
    s/test/full/g
SED_SCRIPT

POSIX sed también es compatible -f, pero el uso de -la entrada estándar no está documentado. En este caso, podría usarlo /dev/stdinen sistemas Linux (y creo recordar que Solaris también tiene esto, pero no puedo confirmarlo en este momento)

El uso <<-SED_SCRIPT(con el prefijo '-') permitirá sangrar la SED_SCRIPTetiqueta de cierre .


Gracias, lo que dijo funcionó, cómo quisiera señalar que el token de cierre no puede sangrarse, de lo contrario, causa un error en bash, supongo que esto se debe a que también incluye el espacio en blanco en el cierre.
Tristian

Tenga en cuenta que Apple OS X sed no admite la lectura de un script desde la entrada estándar. (Al menos no de esa manera ni de ninguna otra manera documentada.)
danorton

@danorton: He añadido una solución que no requiere el apoyo de -f -en sedpero requiere la sustitución de proceso: <( command ).
pabouk

5

En caso de que sedno soporta la lectura de un guión de stdin(usando -f -), puede utilizar la sustitución de proceso (disponible en bash, zsh, ksh93):

sed "$IN" > "$OUT" -f <( cat << SED_SCRIPT
    s/a/1/g
    s/test/full/g
SED_SCRIPT)

El paréntesis de cierre )debe seguir al delimitador final ( SEC_SCRIPT) inmediatamente o después de una nueva línea. En el caso de la sustitución de procesos, también puede usar en echolugar de un documento aquí:

sed "$IN" > "$OUT" -f <( echo \
"    s/a/1/g
    s/test/full/g" )

1
En Mac OS X, no le gustaba el archivo de entrada ( "$IN"o incluso testfile.txt) inmediatamente después del comando sed en sí mismo; quería un -e scripto -f file. Reorganizar la respuesta de @pabouk funcionó para mí:sed -f <( cat << ETC ... ETC) "$IN" > "$OUT"
Stephen P

En Max OSX con bash 4.2.45 y estándar BSD sed, los paréntesis de cierre tenían que estar en una nueva línea debajo del cierre SED_SCRIPT.
Alexander Klimetschek

-1

Quizás un mejor enfoque:

OUT=/dev/stdout

IN=my_in_file.txt
sed -s 's/in/out/' < $IN > $OUT
  -or-
sed -s 's/in/out/' > $OUT < $IN

IN=my_in_text
sed -s 's/in/out/' <<< $IN > $OUT
  -or-
sed -s 's/in/out/' > $OUT <<< $IN

:)


1
Interesante, pero además del punto. El OP quiere pasar comandos sed a través de stdin.
muru

Este enfoque permite ambos métodos, ¿por qué el voto negativo?
Magnus

Repita: "pasar comandos sed a través de stdin". Su respuesta no hace eso por ningún método.
muru
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.