Seleção de texto no Unix usando sed

2

Eu quero selecionar uma parte específica de um arquivo de texto e imprimi-lo / armazená-lo em outro arquivo.

A seleção é iniciada quando um padrão específico corresponde e termina quando outro padrão corresponde. E eu tenho que fazer isso sem o awk. Estou tentando usar sed.

  • inicie a seleção quando for encontrada esperada
  • até quando encontrado real

> |e|build_event_details_json(e) })
       expected collection contained:  [{"id"=>18646, "state"=>"available", "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",actual collection contained:    [{"id"=>18646

resposta deve ser

>  expected collection contained:  [{"id"=>18646, "state"=>"available", "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
    
por Sandy 21.09.2018 / 06:48

4 respostas

0

Usando somente sed:

<infile sed 's/expected/\n&/;s/.*\n//;s/actual/\n&/;s/\nactual.*//'

Explicação:

  • s/expected/\n&/ Coloque uma nova linha (dividir) antes de expected .
  • s/.*\n// Remova a linha principal que o comando anterior criou.
  • s/actual/\n&/ Coloque uma nova linha (dividir) antes de actual .
  • s/\nactual.*// Remova a linha criada acima, começando com actual .

Observe que acima será gerada uma linha vazia se actual estiver no início de uma linha. Se essa linha vazia precisar ser evitada, use:

<infile sed 's/expected/\n&/;s/.*\n//;/^actual/d;s/actual.*//'

Observe também que o (s) comando (s) acima manterão inalteradas todas as linhas que não corresponderem a expected ou actual e, em seguida, serão impressas. Para evitar isso, anexe o /expected\|actual/!d desta forma:

<infile sed '/expected\|actual/!d;s/expected/\n&/;s/.*\n//;/^actual/d;s/actual.*//'

Se o que é necessário é o intervalo de linhas entre expected e actual , mas removendo a linha à direita contendo actual , use:

<infile sed '/^expected/!{s/expected/\n&/};/^actual/!{s/actual.*/\n&/}' |  
        sed '/expected/,/actual/!d;/actual/d'
    
por 26.09.2018 / 05:36
2

Não é muito elegante, nem eficiente, mas faz o trabalho

sed 's/actual/\n&/' file | sed -n '/expected/,/actual/p' | sed '$d'
       expected collection contained:  [{"id"=>18646, "state"=>"available", "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",

Talvez um pouquinho melhor (com GNU sed ):

sed -n '/expected/,$ {s/actual.*$//; p; T; q; } ' file

Se o comando T não estiver disponível, tente

sed -n '/expected/,$ {s/actual.*$//; p; tL; b; :L; q; } ' file
    
por 21.09.2018 / 11:27
0

Acho que isso deve ser feito:

 sed -n '/expected.*actual/{s/actual.*//;p;n};
         /expected/,/actual/{s/actual.*//;p}' input

Se uma linha contiver marcadores de início e fim, descarte tudo após o marcador final e leia a próxima linha. Caso contrário, imprima qualquer coisa entre as linhas que contêm o marcador inicial e final, novamente descartando tudo após o marcador final.

    
por 21.09.2018 / 10:43
0

Parece que você está tentando analisar o JSON com sed. Não é uma boa ideia. Use se possível.

No entanto, você pode fazer o slurp de todo o arquivo na memória e procurar e substituir:

$ cat file
foo
bar
> |e|build_event_details_json(e) })
       expected collection contained:  [
       {"id"=>18646,
       "state"=>"available",
       "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
       actual collection contained:    [
       {"id"=>18646
baz
qux

$ sed -n 'H;${g;s/.*\(expected.*\)actual.*//p}' file
expected collection contained:  [
       {"id"=>18646,
       "state"=>"available",
       "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",

Observe que isso gerará uma saída do último 'esperado' para o último após 'real' devido à ganância do quantificador *

$ cat file
foo
expect1
bar
> |e|build_event_details_json(e) })
       expected collection contained:  [
       {"id"=>18646,
       "state"=>"available",
       "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
       actual collection contained:    [
       {"id"=>18646
baz
actual2
qux

$ sed -n 'H;${g;s/.*\(expected.*\)actual.*//p}' file
expected collection contained:  [
       {"id"=>18646,
       "state"=>"available",
       "salesEndAtUtc"=>"2018-09-22T00:00:00.000Z",
       actual collection contained:    [
       {"id"=>18646
baz
    
por 21.09.2018 / 13:27