Como faço para grip para vários padrões em várias linhas? -- and-line campo com grep campo com text-processing camp askubuntu Relacionado O problema

How do I grep for multiple patterns on multiple lines?


21
vote

problema

português

Para ser preciso

  Some text begin Some text goes here. end Some more text    

e eu quero extrair bloco inteiro que começa de "começar" até "final".

com awk podemos fazer como awk '/begin/,/end/' text .

Como fazer com Grep?

english

To be precise

Some text begin Some text goes here. end Some more text 

and I want to extract entire block that starts from "begin" till "end".

with awk we can do like awk '/begin/,/end/' text.

How to do with grep?

        

Lista de respostas

14
 
vote
vote
Melhor resposta
 

Atualizado 18-Nov-2016 (já que o comportamento do grep é alterado: Grep com parâmetro -p agora não suporta ^ e abcdefghijklmn1 Âncoras [no Ubuntu 16.04 com kernel v: 4.4.0-21-generic]) ( Errado (não) corrigir )

  $ grep -Pzo "begin(.| )* end" file begin Some text goes here.   end    

Nota: Para outros comandos, basta substituir o '^' & amp; Âncoras '$' com âncora de nova linha ' ' ______________________________

com o comando grep:

grep -Pzo "^begin$(.| )*^end$" file

Se você quiser, não inclua os padrões "Begin" e "End" em resultado, use o Grep com o Suporte Lookbehind e LookAhead.

grep -Pzo "(?<=^begin$ )(.| )*(?= ^end$)" file

também você pode usar K notificar em vez da asserção Lookbehind.

grep -Pzo "^begin$ K(.| )*(?= ^end$)" file

K opção ignore tudo antes do padrão correspondente e ignore o próprio padrão.
usado para evitar imprimir linhas vazias de saída.

ou como @AvinoShraj sugere que há simples grep fácil como segue:

$0

$1 informa que o grep permite que o ponto corresponda aos caracteres da Newline.
$2 corresponde a qualquer caractere que seja espaço em branco ou não-branco.

e sua saída sem incluir "begin" e "end" é o seguinte:

$3

Consulte o teste completo de todos os comandos aqui (sub> fora datado como comportamento de Grep com O parâmetro -p é alterado )

NOTA:

$4 apontar o início de uma linha e $5 apontar o final de uma linha. Estes adicionados ao redor de "começar" e "fim" para combiná-los se eles estão sozinhos em uma linha.
Em dois comandos eu escapei $6 porque também está usando para "substituição de comando" ( $7 ) que permite a saída de um comando para substituir o nome do comando.

do homem grep:

$8
 

Updated 18-Nov-2016 (since grep behavior is changed: grep with -P parameter now doesn't support ^ and $ anchors [on Ubuntu 16.04 with kernel v:4.4.0-21-generic])(wrong (non-)fix)

$ grep -Pzo "begin(.|\n)*\nend" file begin Some text goes here.   end 

note: for other commands just replace the '^' & '$' anchors with new-line anchor '\n' ______________________________

With grep command:

grep -Pzo "^begin\$(.|\n)*^end$" file 

If you want don't include the patterns "begin" and "end" in result, use grep with Lookbehind and Lookahead support.

grep -Pzo "(?<=^begin$\n)(.|\n)*(?=\n^end$)" file 

Also you can use \K notify instead of Lookbehind assertion.

grep -Pzo "^begin$\n\K(.|\n)*(?=\n^end$)" file 

\K option ignore everything before pattern matching and ignore pattern itself.
\n used for avoid printing empty lines from output.

Or as @AvinashRaj suggests there are simple easy grep as following:

grep -Pzo "(?s)^begin$.*?^end$" file  grep -Pzo "^begin\$[\s\S]*?^end$" file 

(?s) tells grep to allow the dot to match newline characters.
[\s\S] matches any character that is either whitespace or non-whitespace.

And their output without including "begin" and "end" is as following:

grep -Pzo "^begin$\n\K[\s\S]*?(?=\n^end$)" file # or grep -Pzo "(?<=^begin$\n)[\s\S]*?(?=\n^end$)"  grep -Pzo "(?s)(?<=^begin$\n).*?(?=\n^end$)" file 

see the full test of all commands here (out of dated as grep behavior with -P parameter is changed)

Note:

^ point the beginning of a line and $ point the end of a line. these added to the around of "begin" and "end" to matching them if they are alone in a line.
In two commands I escaped $ because it also using for "Command Substitution"($(command)) that allows the output of a command to replace the command name.

From man grep:

-o, --only-matching       Print only the matched (non-empty) parts of a matching line,       with each such part on a separate output line.  -P, --perl-regexp       Interpret PATTERN as a Perl compatible regular expression (PCRE)  -z, --null-data       Treat the input as a set of lines, each terminated by a zero byte (the ASCII        NUL character) instead of a newline. Like the -Z or --null option, this option        can be used with commands like sort -z to process arbitrary file names. 
 
 
         
         
2
 
vote

Caso o seu $9 não suporte a sintaxe perl ( $ grep -Pzo "begin(.| )* end" file begin Some text goes here. end 0 ), você pode tentar juntar as linhas, correspondendo ao padrão e, em seguida, expandindo as linhas novamente como abaixo:

  $ grep -Pzo "begin(.| )* end" file begin Some text goes here.   end 1   
 

In case your grep doesn't support perl syntax (-P), you can try joining the lines, matching the pattern, then expanding the lines again as below:

$ tr '\n' , < foo.txt | grep -o "begin.*end" | tr , '\n' begin Some text goes here. end 
 
 

Perguntas relacionadas

0  Como faço para copiar o conteúdo de um arquivo e concatenamos em um novo arquivo?  ( How do i copy contents of a file and concatenate it into a new file ) 
Eu tenho que fazer novos arquivos que contenham o conteúdo do arquivo original duas vezes e, em seguida, concatenaram a linha por linha. Por exemplo: File ...

1  Substitua apenas alguns números usando SED [FECHADO]  ( Replace only certain numbers using sed ) 
. fechado . Esta pergunta precisa detalhes ou clareza . Atualmente não está aceitando respostas. ...

5  Analisando um arquivo usando ferramentas de processamento de texto  ( Parsing a file using text processing tools ) 
Um arquivo parece: 1140.271257 0.002288454025 0.002763420728 0.004142512599 0 0 0 0 0 0 0 0 0 0 0 1479.704769 0.00146621631 0.003190634646 0.003672029231 ...

14  Existe uma maneira, idealmente usando a linha de comando, para converter vários arquivos .csv para uma planilha de multi-folha  ( Is there a way ideally using the command line to convert multiple csv files t ) 
Existe uma maneira, idealmente usando a linha de comando, para converter vários arquivos .csv para uma planilha de multi-folha. Se não houver uma solução CL...

22  Como substituir espaços por newlines / enter em um arquivo de texto?  ( How to replace spaces with newlines enter in a text file ) 
Eu tenho um arquivo de texto simples chamado "exemplo". Leitura com o comando terminal: cat example Saída: abc cdef ghi jk lmnopq rst uv wxyz Eu ...

2  Sum Coluna 2 do arquivo .csv Se a coluna 1 for a mesma  ( Sum column 2 of csv file if column 1 is the same ) 
Eu tenho um arquivo CSV onde a coluna 1 é o nome de um gene e coluna 2 é um valor associado a esse gene. No entanto, alguns genes têm vários valores e quero s...

2  Apare o início de um arquivo de texto  ( Trim beginning of a text file ) 
Eu tenho um arquivo de texto com espaços inesperados no começo e gostaria de aparar o começo e salvá-lo. Como posso fazer isso? Eu tentei um exemplo muito s...

3  Como o AWK pode ser usado para listar contêineres de encaixe?  ( How can awk be used to list docker containers ) 
Estou procurando usar ferramentas ao longo das linhas de: grep sed awk Para trabalhar com o Docker. listando contêineres: docker container ls |...

4  Remover citações em torno de números inteiros em um arquivo CSV  ( Remove quotes around integers in a csv file ) 
em um grande arquivo csv (& gt; 1 gb) eu tenho algo como "34432", "name", "0", "very long description" Mas em vez disso gostaria de ter 34432, "name...

1  Usando sed para adicionar caracteres no final de uma linha adiciona uma nova linha  ( Using sed to add characters at the end of a line adds a new line ) 
Eu estou fazendo um script para converter algumas varetas mágicas de um formato para outro. Eu preciso inserir o código SET para cada cartão no final da linha...




© 2022 pergunte.org All Rights Reserved. Casa de perguntas e respostas todos os direitos reservados


Licensed under cc by-sa 3.0 with attribution required.