Extrae líneas entre e incluye 2 patrones

Tengo un file con datos estructurados de la siguiente manera

1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 2, q1, q2, q3, q4, q5, q6, q7 2, q9, q10,, 2, r1, r2, r3, r4, r5, r6, r7 2, r9, r10,, 1, s1, s2, s3, s4, s5, s6, s7 2, s9, s10,, ... 

Quiero get todas las líneas comenzando con 1 y terminando con ,, para que obtenga

 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 1, s1, s2, s3, s4, s5, s6, s7 2, s9, s10,, 

y si es posible conseguirlo,

 1, p1, p2, p3, p4, p5, p6, p7, 2, p9, p10,, 1, s1, s2, s3, s4, s5, s6, s7, 2, s9, s10,, 

¿Cómo puedo hacer esto con sed o awk?

Aquí hay una solución sed que encadena cualquier secuencia de las ,,$ líneas que siguen a la última línea ^1 ocurrida:

 sed -e '/^1/{x;s/\n/ /gp;d' -e '};/,,$/H;$G;D ' <<\IN 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 2, q1, q2, q3, q4, q5, q6, q7 2, q9, q10,, 2, r1, r2, r3, r4, r5, r6, r7 2, r9, r10,, 1, s1, s2, s3, s4, s5, s6, s7 2, s9, s10,, IN 

Cambia h espacios antiguos y patrones en líneas que comienzan con a ^1 y s///p rints sea cual sea el contenido de h old space anterior a eso solo en el caso de una sustitución exitosa. Las líneas que terminan con ,,$ se añaden al espacio H antiguo después de un carácter \n ewline y luego todas las líneas se D eletan hasta el primer carácter \n ewline que se produce. En la última línea $ , el espacio antiguo se agrega al espacio del patrón siguiendo una línea \n ew, de modo que cuando se elige, reinicia el ciclo de línea en la parte superior del script que contiene solo el espacio antiguo que contiene, lo que lo imprime según sea necesario. .

SALIDA:

 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 2, q9, q10,, 2, r9, r10,, 1, s1, s2, s3, s4, s5, s6, s7 2, s9, s10,, 

Si, por otro lado, no desea las subsecuentes /,,$/ ocurrencias entonces esto podría hacer:

 sed -e '/^1/{x;y/\n/ /;s/,,.*/,,/p;d' -e '};/,,$/H;$G;D' 

Dada la misma input que imprime en su lugar:

 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 1, s1, s2, s3, s4, s5, s6, s7 2, s9, s10,, 

Pero eso imprimirá /,,$/ líneas incluso si no siguen inmediatamente una coincidencia /^1/ . Si desea los pares solo si son de input secuencial inmediatamente, puede hacerlo también:

 sed -n '/^1/!d;$p;N;/\n1/P;/,,$/s/\n/ /p;D' 

Eso funciona así:

  • Primero, da de salida todas las líneas que sí lo hacen ! no comenzar con /^1/
    • Esto incluye líneas traídas con N que no terminan con /,,$/ .
  • Si se trata de la última línea de input, se imprime el espacio de patrón de línea, porque el siguiente command finalizará la secuencia de commands.
  • En /^1/ coincide, agrega la línea de input N ext al espacio del patrón siguiendo un caracter \n ewline.
  • Si la línea añadida también comienza con un /\n1/ it Pinta el anterior.
    • P imprime solo hasta la primera línea \n na existente en el espacio del patrón.
  • Después de insert la línea de input N ext si el espacio de patrón $ finaliza con una /,,$/ coincidencia, s/// representa un carácter de espacio para el carácter insertado \n ewline y visualiza los resultados.
  • El espacio de patrón siempre se incluye hasta e incluyendo el primer carácter de \n ewline que se produce.
    • … así que cuando una línea de input N ext no coincide con /,,$/ se envía de vuelta a la parte superior del guión como el encabezado de la línea. Si en ese punto no constring con ^1 , se termina por completo.
    • … porque /,,$/ ya han eliminado por completo su \n ewline, se eliminan del flujo de forma adecuada aquí.

Todo esto significa que si /^1/ lines se siguen entre sí, todavía se imprimen, y si las líneas que no terminan en ,,$ siguen a ^1 , no se imprimen.

En cuanto a su primera consulta, puede usar -e para combinar la expresión en sed:

 ~$ sed -n -e '/^1/p' -e '/,,$/p' f 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 2, p9, p10,, 2, p9, p10,, 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 

y si no quieres el duplicado:

 ~$ sed -n -e '/^1/p' -e '/,,$/p' f | uniq 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 

Con awk, combine la expresión regular con ; :

 ~$ awk '/^1/;/,,$/' f 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 2, p9, p10,, 2, p9, p10,, 1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,, 

Puede configurar ORS condicional para get la salida en el formatting deseado

 awk '/^1/,/,,$/{ORS = /^1/? ", ": "\n"; print}' file 1, p1, p2, p3, p4, p5, p6, p7, 2, p9, p10,, 1, p1, p2, p3, p4, p5, p6, p7, 2, p9, p10,,