¿Usando awko sedcómo puedo seleccionar líneas que ocurren entre dos patrones de marcadores diferentes? Puede haber varias secciones marcadas con estos patrones.
Por ejemplo: suponga que el archivo contiene:
abc
def1
ghi1
jkl1
mno
abc
def2
ghi2
jkl2
mno
pqr
stu
Y el patrón inicial es abcy el patrón final es mno
Entonces, necesito la salida como:
def1
ghi1
jkl1
def2
ghi2
jkl2
Estoy usando sed para que coincida con el patrón una vez:
sed -e '1,/abc/d' -e '/mno/,$d' <FILE>
¿Hay alguna manera en sedo awk hacerlo varias veces hasta el final del archivo?

awk '/abc/{a=1}/mno/{print;a=0}a' file.awk '/abc/{a=1} a; /mno/{a=0}' file- con esto, poniendoacondición antes de la/mno/hacemos evaluar la línea como verdadera (e imprimirla) antes de configurara=0. De esta forma podemos evitar escribirprint.awk '/abc/,/mno/' fileawk '/abc/{flag=1}/mno/{flag=0}flag' filedebería hacer.awk 'flag; /PAT1/{flag=1; next} /PAT1/{flag=0}' filelo haría.Usando
sed:La
-nopción significa no imprimir de forma predeterminada.El patrón busca líneas que contengan solo
abcto justmnoy luego ejecuta las acciones en el{ ... }. La primera acción borra laabclínea; el segundo lamnolínea; epimprime las líneas restantes. Puede relajar las expresiones regulares según sea necesario. Cualquier línea fuera del rango deabc..mnosimplemente no se imprime.fuente
-eseddebe ejecutarse. Si desea o necesita usar varios argumentos para incluir el script completo, debe usarlos-eantes de cada uno de esos argumentos; de lo contrario, es opcional (pero explícito).da todas las líneas hasta la primera coincidencia, y luego otrada todas las líneas que comienzan con la segunda coincidencia?Esto podría funcionar para usted (GNU sed):
Elimine todas las líneas excepto aquellas entre las líneas que comienzan
abcymnofuente
!d;//dgolfs 2 caracteres mejor :-) stackoverflow.com/a/31380266/895245{//!b}evita queabcymnose incluyan en la salida, pero no puedo entender cómo. ¿Podrías explicar?//!blee si la línea actual no es ninguna de las líneas que coinciden con el rango, se rompe y, por lo tanto, imprime esas líneas; de lo contrario, todas las demás líneas se eliminan.golf dos personajes mejor que ppotong
{//!b};dLas barras diagonales vacías
//significan: "reutilizar la última expresión regular utilizada". y el comando hace lo mismo que el más comprensible:Esto parece ser POSIX :
fuente
De los enlaces de la respuesta anterior, el que lo hizo por mí, que se ejecuta
kshen Solaris, fue este:1,/firstmatch/d: desde la línea 1 hasta la primera vez que encuentrefirstmatch, elimine./secondmatch/,$d: desde la primera aparición desecondmatchhasta el final del archivo, eliminar.fuente
1,) viene antes/firstmatch/? Supongo que esto también podría expresarse'/firstmatch/1,d;/secondmatch,$d'.fuente
algo como esto funciona para mí:
file.awk:
utilizando:
awk -f file.awk data...editar: La solución O_o fedorqui es mucho mejor / más bonita que la mía.
fuente
if (record=1)debería serif (record==1), es decir, doble=- ver operadores de comparación de gawkLa respuesta de Don_crissti de ¿ Mostrar solo texto entre 2 patrones coincidentes ?
que es mucho más eficiente que la aplicación de AWK, consulte aquí .
fuente
Intenté usar
awkpara imprimir líneas entre dos patrones mientras que el patrón2 también coincide con el patrón1 . Y la línea pattern1 también debe imprimirse.por ejemplo, fuente
debería tener una salida de
Donde patrón1 es
package BBB, patrón2 espackage \w*. Tenga en cuenta queCCCno es un valor conocido, por lo que no se puede comparar literalmente.En este caso, ni @scai's
awk '/abc/{a=1}/mno/{print;a=0}a' fileni @fedorqui'sawk '/abc/{a=1} a; /mno/{a=0}' filefuncionan para mí.Finalmente logré solucionarlo
awk '/package BBB/{flag=1;print;next}/package \w*/{flag=0}flag' filejajaUn poco más de esfuerzo resulta en
awk '/package BBB/{flag=1;print;next}flag;/package \w*/{flag=0}' fileimprimir también la línea patrón2, es decir,fuente