Removendo texto do padrão1 até e incluindo a segunda correspondência do padrão2?

3

Eu tenho um arquivo de texto assim:

<!--START OF FILE -->
random text
<meta> more random text </meta>
x x x x x x x 
more random text
that I dont need 
x x x x x x x

I need everything
from this point
onwards
...

Eu preciso remover tudo entre <!--START OF FILE --> e o segundo x x x x x x x assim:

I need everything
from this point
onwards
...

Eu tentei usar sed '/<!--START OF FILE -->/,/x x x x x x x/d' test.txt , mas isso remove o bloco entre a primeira ocorrência de x x x x x x x , que não é o que eu quero.

    
por fsociety 24.12.2017 / 10:23

4 respostas

3

Isso é exatamente o oposto de

Como imprimir linhas entre padrão1 e segundo jogo do padrão2?

Com sed você faria algo como:

sed -n '/PATTERN1/,$!{         # if not in this range
p;d                            # print and delete
}
/PATTERN2/!d                   # delete if it doesn't match PATTERN2
x;//!d                         # exchange and then, again, delete if no match
: do                           # label "do" (executed only after the 2nd match)
n;p                            # get the next line and print
b do' infile                   # go to label "do"

ou, em uma linha (em gnu setups):

sed -n '/PATTERN1/,$!{p;d;};/PATTERN2/!d;x;//!d;: do;n;p;b do' infile

Claro, é mais fácil com awk e contadores. Vou deixar isso como um exercício para você ...

    
por 24.12.2017 / 12:14
1

Direto awk :

$ awk '/<!--START OF FILE -->/ {a=2}; !a; /x x x x x x x/ && a {a--}' < data

I need everything
from this point
...

Ele é impresso sempre que a é zero e diminui quando ele vê o x x x ... .

Ou, a partir do início real do arquivo, em vez de um padrão, altere o primeiro bloco para BEGIN {a=2} .

Observe que sua entrada de amostra tem uma linha vazia após o segundo x x x... e permanece na saída se pararmos de remover linhas na linha x x x... .

    
por 24.12.2017 / 19:41
0
grep -Pz '(?s)<!--START OF FILE(.*?x x x x x x x){2}\K.*' input.txt

Explicação

  1. grep -Pz

    • -P - Interpreta o padrão como uma expressão regular compatível com Perl (PCRE).
    • -z - processa o input.txt como uma grande linha.
  2. (?s)<!--START OF FILE(.*?x x x x x x x){2}\K.*

    • (?s) - Ativar "ponto corresponde a nova linha" para o restante da expressão regular.
    • .*? - correspondência não-gulosa.
    • {2} - quantidade de repetições do padrão.
    • \K - qualquer caractere com correspondência anterior a ser omitido da string final correspondente.
por 24.12.2017 / 12:08
0

Este snippet:

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
pl " Input data file $FILE:"
head -v -n 20 $FILE

pl " Expected output on file $E:"
head -v $E

pl " Results:"
cgrep -V -D -w '<!--START OF FILE -->' +2 +w 'x x x x x x x' 'meta' $FILE

produz:

-----
 Input data file data1:
==> data1 <==
<!--START OF FILE -->
random text
<meta> more random text </meta>
x x x x x x x 
more random text
that I dont need 
x x x x x x x

I need everything
from this point

-----
 Expected output on file expected-output1:

I need everything
from this point
onwards
...

-----
 Results:

I need everything
from this point
onwards
...

Isto omite (-V) uma janela começando (-w) com '... START ...' e terminando (+ w) com a segunda ocorrência (+2) de uma string '... x x ... 'que tem a string' meta 'dentro da janela.

Em um sistema como:

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.9 (jessie) 
bash GNU bash 4.3.30

Alguns detalhes para o cgrep:

cgrep   shows context of matching patterns found in files (man)
Path    : ~/executable/cgrep
Version : 8.15
Type    : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)
Home    : http://sourceforge.net/projects/cgrep/ (doc)

Embora seja necessário obter e compilar o cgrep, não tive problemas em fazê-lo em sistemas de 32 ou 64 bits e está disponível no macOS (High Sierra) com brew. O tempo de execução está no mesmo nível do GNU grep.

Felicidades ... felicidades, drl

    
por 24.12.2017 / 19:13