Estoy tratando de encontrar un patrón usando sed
comando en file.txt
entre el primer char1 y char2 y luego reemplázalo con una cadena. como abajo con echo
ejemplo de modo:
echo "This X is test Y. But X is not test Y." | sed 's/X[^Y]*Y/REPLACE/'
También necesito guardar el patrón coincidente (como is test
{<–los espacios alrededor son importantes}) en una variable.
Respuesta aceptada:
Aquí hay una única invocación de sed que escribe la línea revisada en stdout y al mismo tiempo guarda el texto eliminado en la variable de shell var
:
$ var=$(echo "This X is test Y. But X is not test Y." | sed -nr 'h;s/[^X]*X([^Y]*)Y.*/\1/;p;x;s/X[^Y]*Y/REPLACE/;w /dev/stderr') 2>&1
This REPLACE. But X is not test Y.
El valor de var
es:
$ echo "==$var=="
== is test ==
Explicación:
-
h
Este comando copia el patrón actual en el espacio de espera.
-
s/[^X]*X([^Y]*)Y.*/\1/;p
Esto elimina todo del espacio del patrón excepto el texto entre la primera
X
yY
incluyendo cualquier espacio. Esto luego se imprime en la salida estándar. Esta es la salida capturada por el shell y asignada avar
. -
x
Esto copia el espacio de espera de vuelta al espacio patrón. Cuando se hace esto, el espacio del patrón contiene una copia de la línea de entrada original.
-
s/X[^Y]*Y/REPLACE/; w /dev/stderr
Se realiza la sustitución y el resultado se escribe en
stderr
. -
2>&1
Después de que el shell haya capturado la salida estándar en
var
, esto le indica al shell que copie stderr (que tiene la línea con REPLACE) a stdout.
Aparte del manejo de la variable var
La variable var
incluye los espacios iniciales y finales. Si el shell sometiera posteriormente a var
a la división de palabras, estos espacios serían eliminados. Para evitar eso, cuando var
se hace referencia, hágalo entre comillas dobles, como en el ejemplo anterior.