Usando sed, adicione as linhas da linha X acima da correspondência

0

Eu sei que para adicionar / acrescentar algo, eu só tenho que fazer:

sed -i '/pattern/a new thing!'

No entanto, eu gostaria de combinar uma linha e adicionar duas linhas acima.

Gostaria de limitar as ferramentas apenas àquelas que saem da caixa com o Ubuntu 12.04, não sei se awk se encaixa no projeto.

Apenas no caso de eu estar buscando solução para o problema B enquanto preciso de solução para A: Excerto do arquivo .m3u8 se parece com isto:

#EXTINF:4.304300,
output-000.ts
#EXTINF:5.705700,
output-001.ts
#EXTINF:4.304300,
output-002.ts
#EXTINF:5.705700,
output-003.ts

Agora, meu objetivo é inserir uma linha 2 linhas antes de cada X'th output-XXX.ts . Por exemplo, eu quero conseguir isso:

#Inserted line 0
#EXTINF:4.304300,
output-000.ts
#EXTINF:5.705700,
output-001.ts
#Inserted line 1
#EXTINF:4.304300,
output-002.ts
#EXTINF:5.705700,
output-003.ts
    
por Misiur 05.05.2015 / 18:03

2 respostas

2

Com awk (instalado por padrão nos sistemas POSIX, incluindo o Ubuntu):

POSIXLY_CORRECT=1 awk -v X=2 '
  NR >= 2 && /^output-[0-9]{3}\.ts$/ && ++n % X == 1 {
    print "#Inserted line", i++
  }
  NR>1 {print last}
  {last = $0}
  END{if (NR) print last}' < file.in > file.out

Isso é para 2 linhas acima. Para generalizar para N linhas acima:

POSIXLY_CORRECT=1 awk -v N=2 -v X=2 '
  BEGIN{N--}
  NR > N {
    if (/^output-[0-9]{3}\.ts$/ && ++n % X == 1)
      print "#Inserted line", i++
    print l[NR % N]
  }
  {l[NR % N] = $0}
  END{
    for (i = NR > N ? NR - N + 1 : 1; i <= NR; i++) print l[i % N]
  }'
    
por 05.05.2015 / 18:24
2

Perl para o resgate:

< .m3u8  perl -ne 'push @w, $_;
                   unshift @w, "#Inserted line " . (0 + $c++) . "\n"
                       if /^output-[0-9]+\.ts/ && 0 == $m++ % 2;
                   print shift @w while @w > 1;
                   }{ print @w;'

@w é a matriz "janela deslizante" que mantém as duas últimas linhas. $m contém o número de correspondências, ou seja, o número de linhas "output-XXXX" encontradas até o momento, portanto, se o módulo 2 der 0, você pegará cada segunda partida. unshift insere uma linha na matriz da janela no início, shift a recupera. No final, você tem que imprimir as linhas restantes.

    
por 05.05.2015 / 18:16