Aqui está uma solução sed
que irá juntar qualquer seqüência das linhas ,,$
após a última ^1
line:
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
Ele e x
alteram h
espaços antigos e padrões nas linhas que começam com ^1
e s///p
rints, independentemente do conteúdo do h
old space anterior àquele no caso de um êxito substituição. As linhas que terminam com ,,$
são anexadas a H
old space após um caractere \n
ewline e, em seguida, todas as linhas são D
eletidas até o primeiro caractere \n
ewline. No espaço $
última linha H
antigo é anexado ao espaço padrão após um \n
ewline - assim, quando é D
eleted, ele reinicia o ciclo de linha na parte superior do script contendo apenas o que H
old espaço contido - que é impresso conforme necessário.
OUTPUT:
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,,
Se, por outro lado, você não quiser as ocorrências /,,$/
subseqüentes, isso poderá acontecer:
sed -e '/^1/{x;y/\n/ /;s/,,.*/,,/p;d' -e '};/,,$/H;$G;D'
Com base na mesma entrada que é impressa:
1, p1, p2, p3, p4, p5, p6, p7 2, p9, p10,,
1, s1, s2, s3, s4, s5, s6, s7 2, s9, s10,,
Mas isso fará com que /,,$/
linhas sejam impressas, mesmo que elas não sigam imediatamente uma correspondência /^1/
. Se você quer os pares apenas se eles são imediatamente sequenciais na entrada - você pode fazer isso também:
sed -n '/^1/!d;$p;N;/\n1/P;/,,$/s/\n/ /p;D'
Isso funciona assim:
- Primeiro
d
elimina da saída todas as linhas que!
não começam com/^1/
- Isso inclui as linhas trazidas com
N
que não terminam com/,,$/
.
- Isso inclui as linhas trazidas com
- Se o espaço de padrão da última linha de entrada
$
for o espaço aquip
rinted, porque o próximo comando encerrará o script. - Em
/^1/
corresponde anexa a linha de entradaN
ext ao espaço padrão seguindo um caractere\n
ewline. - Se a linha anexada também começar com
/\n1/
itP
rints a anterior.-
P
imprime apenas até o primeiro\n
ewline no espaço padrão.
-
- Depois de extrair a linha de entrada
N
ext se o espaço de padrão$
terminar com uma correspondência/,,$/
,s///
ubstittará um caractere de espaço para o caractere\n
ewline inserido ep
rints os resultados. - O espaço padrão é sempre
D
eletido até e incluindo o primeiro caractere\n
ewline que ocorre.- ... assim, quando uma linha de entrada
N
ext não corresponde a/,,$/
, ela é enviada de volta para o início do script como o cabeçalho da linha. Se, nesse ponto, ele não corresponder a^1
, ele serád
totalmente eliminado. - ... porque
/,,$/
já tiveram seu\n
ewline completamente removido por este ponto, eles são removidos do fluxo completamente aqui.
- ... assim, quando uma linha de entrada
Tudo isso significa que se /^1/
linhas se seguirem, elas ainda serão impressas e se as linhas que não terminarem em ,,$
seguirem um ^1
, elas não serão impressas.