Imprimindo a enésima gama com sed

1

Eu posso imprimir as linhas no arquivo a

first
[
third
fourth
]
sixth
[
eighth 
]
tenth

fazendo

% <a sed -n '/\[/,/\]/p' 

que imprime

[
third
fourth
]
[
eighth
]

Mas e se eu quiser apenas o segundo jogo, ou seja. as últimas três linhas?

    
por Toothrot 05.08.2018 / 13:03

3 respostas

0

Mais fácil fazer com awk , supondo que os blocos definidos por [ e ] não contenham [ ou ] dentro do bloco

$ awk -v b=2 '/\[/{c++} c==b; /]/ && c==b{exit}' ip.txt
[
eighth 
]
  • -v b=2 variable para especificar qual bloco é necessário
  • /\[/{c++} contador de incremento se a linha corresponder à condição inicial
  • c==b; imprime o registro de entrada se o contador for igual ao bloco necessário
  • /]/ && c==b{exit} exit na condição final correspondente

outra maneira de escrever isso:

awk -v b=2 '/\[/{c++} c==b{print $0; if(/]/) exit}' ip.txt
    
por 05.08.2018 / 13:19
0
$ sed -n '/^\[/h; /^\[/,/^\]/H; ${x;s/^\[\n//;p;}' file
[
eighth
]

Script sed anotado (assume -n ):

/^\[/h;         # replace hold space with this line
/^\[/,/^\]/H;   # append these lines to hold space with embedded newlines
${              # at last line of input
    x;          # swap in the hold space
    s/^\[\n//;  # delete the first "[" and the newline following it
    p;          # print
}

Ou seja, sempre que encontrarmos uma linha que começa com [ , limpe o espaço de espera copiando a linha para lá. Em seguida, continue anexando linhas ao espaço de espera até encontrar a linha correspondente que começa com ] .

No final, teremos um espaço de espera com um [ demais, portanto, exclua-o (e a nova linha incorporada após ele) antes de imprimir os dados.

    
por 05.08.2018 / 13:39
0

Usando o editor sed , podemos realizá-lo da seguinte maneira:

sed -ne '                    ;# "-n" suppresses autoprint of pattern space
    /^\[/!d                  ;# skip lines that donot begin a fresh block
    :a;$!N;/\n]/!ba          ;# keep appending lines to pattern space until end of block
    G                        ;# append our makeshift counter (hold space) to pattern spc
    s/\n\{2\}$//p            ;# only when counter had 2 chars in it, we print block
    /\n$/!q                  ;# target block, 2nd block has been printed so quit 
    x;s/$/\n/;x              ;# target block not reached, so increment
' input.file

com Perl , podemos usar o operador ... em conjunto com o booleano $ k == 2, indicando que alcançamos o bloco de destino pretendido e precisamos imprimi-lo.

perl -lne 'print if /^\[/ && ++$k == 2 ... /^]/' input.file    
    
por 05.08.2018 / 18:38