Com sed
, você pode fazer:
sed '/\n/P;//d;s/[^?]*/\n&\n/[num];D'
... onde você substituiria o [num]
acima por algum número representando a ocorrência desejada.
Se a ocorrência numerada que você especificar não existir, conforme demonstrado no exemplo a seguir, sed
simplesmente imprimirá nada.
echo ,2,3 | sed '/\n/P;//d;s/[^,]*/\n&\n/4;D'
Acima da primeira correspondência para uma seqüência de zero ou mais caracteres não-vírgula são os caracteres zero que ocorrem antes da primeira vírgula. O segundo é 2
e o terceiro é 3
- não há quarta ocorrência desse padrão e, portanto, a substituição não é bem-sucedida.
Observe também que nem todo sed
suportará o escape \n
newline no campo de substituição do lado direito e talvez seja necessário substituir os caracteres n
na sequência de escape por novas linhas literais.
sed '/\n/P;//d;s/[^?]*/\
&\
/[num];D'
Com sua string, ele:
str='> Leslie Cheung April 1 ? Elvis August 16 ? Leonard Nimoy February 27'
for o in 1 2 3
do printf %s\n "$str" |
sed "/\n/P;//d;s/[^?]*/\n:$o:&\n/$o;D"
done
... que é apenas um pequeno for
loop que executa sed
3 vezes tentando todos os 3 [^?]*
correspondências e imprime ...
:1:> Leslie Cheung April 1
:2: Elvis August 16
:3: Leonard Nimoy February 27
... ou um para cada valor de $o
.
Você pode expandir um pouco para pular as ocorrências de [num]
não-nulo, como:
i=
until [ "$((i+=1))" -gt 10 ] &&
printf %s\n "$str"
do printf %s ":$i:$str?"; done |
sed '/..*\n?*/P;s///;s/[^?]*/\n&\n/7;D'
... que imprime ...
:3:> Leslie Cheung April 1
Elvis August 16
Leonard Nimoy February 27
:10:> Leslie Cheung April 1
Também pode ser inclusive . Por exemplo:
printf %s\n "$str?$str" |
sed '/.*\n[^_[:alnum:]]*/P;s///
s/[_[:alnum:]]\{1,\}/\n&\n/3;D'
... que imprime cada uma em uma linha separada a cada terceira seqüência não nula de caracteres alfanuméricos e _
em uma concatenação de duas de suas strings ...
April
August
Nimoy
Leslie
1
16
February