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:
-
hEste comando copia el patrón actual en el espacio de espera.
-
s/[^X]*X([^Y]*)Y.*/\1/;pEsto elimina todo del espacio del patrón excepto el texto entre la primera
XyYincluyendo cualquier espacio. Esto luego se imprime en la salida estándar. Esta es la salida capturada por el shell y asignada avar. -
xEsto 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/stderrSe realiza la sustitución y el resultado se escribe en
stderr. -
2>&1Despué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.