sustituir script reemplazar linea insertar especiales comando caracteres caracter cadena buscar añadir sed awk matching

script - Imprimir con sed o awk una línea siguiendo un patrón coincidente



sed reemplazar/ (7)

En realidad sed -n ''/pattern/{n;p}'' filename fallará si el pattern coincide con líneas continuous :

$ seq 15 |sed -n ''/1/{n;p}'' 2 11 13 15

Las respuestas esperadas deberían ser:

2 11 12 13 14 15

Mi solución es:

$ sed -n -r ''x;/_/{x;p;x};x;/pattern/!s/.*//;/pattern/s/.*/_/;h'' filename

Por ejemplo:

$ seq 15 |sed -n -r ''x;/_/{x;p;x};x;/1/!s/.*//;/1/s/.*/_/;h'' 2 11 12 13 14 15

Explica:

  1. x; : al comienzo de cada línea desde la entrada, use el comando x para intercambiar los contenidos en el pattern space y hold space .
  2. /_/{x;p;x}; : si el pattern space , que es el hold space realidad, contiene _ (esto es solo un indicator indica si la última línea coincidió con el pattern o no), utilice x para intercambiar el contenido real de current line por pattern space , use p para imprimir current line , y x para recuperar esta operación.
  3. x : recuperar los contenidos en el pattern space y hold space .
  4. /pattern/!s/.*// : si current line NO coincide con el pattern , lo que significa que NO debemos imprimir la siguiente línea SIGUIENTE, entonces use s/.*// comando s/.*// para borrar todo el contenido en el pattern space .
  5. /pattern/s/.*/_/ : si current line coincide con el pattern , lo que significa que debemos imprimir la siguiente línea SIGUIENTE, entonces debemos establecer un indicator para indicarle a sed que imprima la línea NEXT, así que use s/.*/_/ para sustituir todo el contenido en el pattern space por un _ (el segundo comando lo usará para juzgar si la última línea coincide con el pattern o no).
  6. h : sobrescribe el hold space con los contenidos en el pattern space ; luego, el contenido en el hold space es ^_$ que significa que current line coincide con el pattern , o ^$ , lo que significa que current line NO coincide con el pattern .
  7. el quinto y el sexto paso NO pueden intercambiarse, porque después de s/.*/_/ , el pattern space del pattern space NO puede coincidir /pattern/ , por lo que s/.*// DEBE ejecutarse.

Me gustaría imprimir una sola línea directamente siguiendo una línea que contenga un patrón coincidente. Mi versión de sed no tomará la siguiente sintaxis (explota en +1p .) Que parecería una solución simple:

sed -n ''/ABC/,+1p'' infile

Supongo que awk sería mejor hacer procesamiento de líneas múltiples, pero no estoy seguro de cómo hacerlo.


Es la línea después de ese partido en la que estás interesado, ¿verdad? En Sed, eso podría lograrse así:

sed -n ''/ABC/{n;p}'' infile

Alternativamente, la opción A de grep puede ser lo que estás buscando.

-A NUM, Print NUM lines of trailing context after matching lines.

Por ejemplo, dado el siguiente archivo de entrada:

foo bar baz bash bongo

Puede usar lo siguiente:

$ grep -A 1 "bar" file bar baz $ sed -n ''/bar/{n;p}'' file baz

Espero que ayude.


Esto podría funcionar para usted (GNU sed):

sed -n '':a;/regexp/{n;h;p;x;ba}'' file

Use la opción sep grep-like y si la línea actual contiene la expresión regular requerida reemplace la línea actual con la siguiente, copie esa línea en el espacio de espera (HS), imprima la línea, cambie el espacio del patrón (PS) para el HS y repetir.


Necesitaba imprimir TODAS las líneas después del patrón (ok Ed, REGEX), así que me decidí por este:

sed -n ''/pattern/,$p'' # prints all lines after ( and including ) the pattern

Pero como quería imprimir todas las líneas DESPUÉS (y excluir el patrón)

sed -n ''/pattern/,$p'' | tail -n+2 # all lines after first occurrence of pattern

Supongo que en tu caso puedes agregar una head -1 al final

sed -n ''/pattern/,$p'' | tail -n+2 | head -1 # prints line after pattern


Nunca use la palabra "patrón", ya que es muy ambigua. Siempre use "string" o "regexp" (o en shell "globbing pattern"), lo que sea que realmente quiera decir.

La respuesta específica que desea es:

awk ''f{print;f=0} /regexp/{f=1}'' file

o especializando la solución más general del N-ésimo registro después de una expresión regular (modismo "c" a continuación):

awk ''c&&!--c; /regexp/{c=1}'' file

Los siguientes modismos describen cómo seleccionar un rango de registros dada una expresión regular específica para que coincida:

a) Imprime todos los registros de algunos regexp:

awk ''/regexp/{f=1}f'' file

b) Imprima todos los registros después de algunos regexp:

awk ''f;/regexp/{f=1}'' file

c) Imprima el N-ésimo registro después de algunas expresiones regulares:

awk ''c&&!--c;/regexp/{c=N}'' file

d) Imprima todos los registros, excepto el N-ésimo registro después de algunos regexp:

awk ''c&&!--c{next}/regexp/{c=N}1'' file

e) Imprima los N registros después de algunos regexp:

awk ''c&&c--;/regexp/{c=N}'' file

f) Imprima todos los registros excepto los N registros después de algunos regexp:

awk ''c&&c--{next}/regexp/{c=N}1'' file

g) Imprima los N registros de algunos regexp:

awk ''/regexp/{c=N}c&&c--'' file

Cambié el nombre de la variable de "f" por "encontrado" a "c" por "conteo" cuando correspondía, ya que eso es más expresivo de lo que realmente es la variable.


Si coincide el patrón, copie la siguiente línea en el buffer del patrón, elimine un retorno, luego déjelo - el efecto secundario es imprimir.

sed ''/pattern/ { N; s/.*/n//; q }; d''


Versión de awk:

awk ''/regexp/ { getline; print $0; }'' filetosearch