Extraia linhas de um arquivo que contenha De str1 Para str2

2

Digamos que existe um arquivo "abc.txt" que contém um parágrafo / linhas:

Hello, how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch the train?

Como posso extrair todos os caracteres no arquivo de "como" para "capturar"?

    
por Pujan Sinha 21.09.2014 / 07:14

5 respostas

4

Se você tem uma versão do grep que suporta o PCRE, você pode usar o seguinte comando para fazer o que quiser:

$ grep -Pzo 'how.*\n.*catch' file 
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch

Os interruptores:

  • -P - ativa PCRE - Expressões regulares compatíveis com Perl
  • -z - Emita um byte zero (o caractere NUL ASCII) em vez do caractere que normalmente segue um nome de arquivo. Por exemplo, grep -lZ gera um byte zero após cada nome de arquivo em vez da nova linha usual. Essa opção torna a saída não ambígua, mesmo na presença de nomes de arquivos que contenham caracteres incomuns, como novas linhas. Essa opção pode ser usada com comandos como find -print0, perl -0 , sort -z e xargs -0 para processar nomes de arquivos arbitrários, mesmo aqueles que contêm caracteres de nova linha.
  • -o - Imprime apenas as partes correspondentes (não vazias) de uma linha correspondente, com cada uma dessas partes em uma linha de saída separada.
por 21.09.2014 / 14:40
3

A ferramenta certa para este trabalho é pcregrep

pcregrep -oM "how(.|\n)*catch" SPEC
  • pcregrep : um grep com expressões regulares compatíveis com Perl.
  • -o : mostra apenas a parte da linha que correspondeu a um padrão
  • -M : permite que os padrões correspondam a mais de uma linha
  • (.|\n)* : corresponde a qualquer caractere ou nova linha zero ou mais vezes

Se você quiser uma versão não-voraz, adicione ? após * :

pcregrep -oM "how(.|\n)*?catch" SPEC
    
por 21.09.2014 / 14:53
2

Usando sed

Esta resposta assume que você tem uma boa qualidade sed que pode lidar com linhas longas. Supondo que seu texto esteja no arquivo chamado file :

$ tr '\n' '
$ awk '/how/{f=1;sub(/.*how/,"how")} /catch/{f=0;sub(/catch.*/,"catch");print} f' file
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch
1' <file | sed -n -r 's/.*(how.*catch).*/\n/p' | tr '
$ tr '\n' '
$ awk '/how/{f=1;sub(/.*how/,"how")} /catch/{f=0;sub(/catch.*/,"catch");print} f' file
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch
1' <file | sed -n -r 's/.*(how.*catch).*/\n/p' | tr '%pre%1' '\n' how are you doing sir? when are you going to arrive at the SBAHN platform to catch
1' '\n' how are you doing sir? when are you going to arrive at the SBAHN platform to catch

Explicação:

  • tr '\n' 'file1' <file

    Isso lê o arquivo sed -n -r 's/.*(how.*catch).*/\n/p' e substitui todos os caracteres de nova linha por caracteres octal 001. Isso tem o efeito de converter a entrada em uma única linha.

  • sed

    Agora que a entrada é uma única linha, -n pode manipular essa tarefa facilmente. O comando de substituição acima captura todo o texto de "como" para "capturar" e o imprime para stdout

    Como a opção how.*catch é usada, nada é impresso, a menos que a expressão regular corresponda. Assim, se a entrada não tiver uma sequência tr 'sed1' '\n' , nada será impresso.

  • awk

    Isso converte os caracteres octal 001 em novas linhas.

O octal 001 pode ser substituído por qualquer caractere que (a) você tenha certeza de que não está em seu arquivo de entrada e que (b) seu /how/{f=1;sub(/.*how/,"how")} possa manipular corretamente.

Usando f

%pre%

Explicação:

  • /catch/{f=0;sub(/catch.*/,"catch");print}

    Se a linha contiver a palavra "como", isso removerá todo o texto anterior ao "como" e definirá a variável de sinalização f para 1

  • f

    Se a linha contiver a palavra "catch", isso removerá todo o texto após o "catch", definirá a variável de sinalização f==0 para 0 e imprimirá a linha revisada.

  • %code%

    Se o sinalizador for 1, este comando awp um pouco enigmático fará com que a linha seja impressa. Se %code% , nada será impresso.

por 21.09.2014 / 07:38
1

Você pode fazer isso através do Perl,

$ perl -000pe 's/.*(how.*?catch).*/\n/s' file
how are you doing sir? 
when are you going to arrive at the SBAHN platform to catch
    
por 21.09.2014 / 08:35
1

O exemplo sed falhará se o texto não fizer parte do arquivo e, em seguida, você obterá o arquivo completo em vez de nada.

Use grep em vez de sed:

tr '\n' '
tr '\n' '%pre%1' < file | grep -o -E 'how.*catch' | tr '%pre%1' '\n' 
1' < file | grep -o -E 'how.*catch' | tr '%pre%1' '\n'

Correspondência gananciosa e não-gananciosa também é um problema, portanto, se o "catch" estiver na linha 2 e outro na linha 5, você deseja uma correspondência não-gananciosa.

Leia aqui como conseguir isso, depende muito da versão grep :

link

    
por 21.09.2014 / 14:18