Como dizer ao grep para combinar um caracter especial no início de cada palavra [duplicado]

4

Eu tenho algumas perguntas sobre grep .

  1. Por que o seguinte comando corresponde a ' <Hello '?

    $ grep -E "\<H" test
    Hello World
    <Hello
    H<ello
    
  2. O que precisa ser feito para corresponder apenas a ' <Hello '?

por user3539 05.03.2013 / 08:30

2 respostas

5

Para impedir que grep interprete uma string especialmente (uma expressão regular), use -F (ou --fixed-string ):

$ cat test
one < two
Hello World
X<H
A <H A
I said: <Hello>
$ grep -F '<H' test
X<H
A <H A
I said: <Hello>

Lembre-se de citar o padrão de pesquisa corretamente, caso contrário, ele pode ser interpretado mal pelo seu shell. Por exemplo, se você executou grep -F <H test , o shell tentará abrir um arquivo chamado "H" e usá-lo para alimentar a entrada padrão de grep . grep pesquisará a string "test" nesse fluxo. Os seguintes comandos são aproximadamente equivalentes entre si, mas não ao acima:

 grep -F <H test
 grep -F test <H         # location of '<H' does not matter
 grep -F H test
 cat H | grep -F test    # useless cat award

Apenas para palavras correspondentes, dê uma olhada na página de manual grep(1) :

   -w, --word-regexp
          Select  only those lines containing matches that form whole words.  The
          test is that the matching substring must either be at the beginning  of
          the  line, or preceded by a non-word constituent character.  Similarly,
          it must be either at the end of the line  or  followed  by  a  non-word
          constituent   character.    Word-constituent  characters  are  letters,
          digits, and the underscore.

Exemplo de uso (usando o arquivo de teste acima):

$ grep -F -w '<H' test
A <H A

( -F é opcional aqui porque <H não tem um significado especial, mas se você pretende estender este padrão literal, pode ser útil então)

Para corresponder ao início de uma palavra, você precisa de expressões regulares:

$ grep -w '<H.*' test    # match words starting with '<H' followed by anything
A <H A
I said: <Hello>
    
por 05.03.2013 / 22:22
2

< não é um caractere especial em nenhum grep. No entanto, no GNU grep \< é especial e significa o início da palavra (portanto, o limite de largura zero antes de Hello em todas as linhas de entrada).

Em todo grep s \ é especial. Ele pode escapar de um caractere especial para remover seu significado especial (por isso é correspondido literalmente) ou adicionar um significado especial a um caractere (normalmente usado para introduzir novos operadores sem quebrar scripts existentes, outra maneira é usar coisas que seriam inválidas como *? ou (? ) ou para sequências de escape ANSI C como \n , \t ...

Para remover o significado especial de \ , como os outros, você precisa de outro \ .

Então, para corresponder a <Hello , você precisa:

grep -E '<Hello'

E para corresponder a \<Hello , você precisa de:

grep -E '\<Hello'

Note que < e \ são especiais para o shell , assim também é necessário citar para o shell , portanto, as aspas simples acima ( \ também é especial (para o shell) entre aspas duplas, embora apenas na frente de outros caracteres especiais dentro de aspas, como nova linha, aspas duplas, barra invertida, dólar ou backtick, para que você não tenha grep -E "\\<Hello" ou grep -E "\\<Hello" \<Hello ).

Para que o padrão corresponda à linha completa, adicione a opção -x ao grep:

grep -xE '<Hello'

corresponderia apenas às linhas cujo conteúdo é exatamente "<Hello" .

Para corresponder no início da linha:

grep -E '^<Hello'

(corresponderia a "<Hello" e "<Hello world>" , mas não a World <Hello .

Para corresponder <Hello não precedido por um caracter não-branco (minha interpretação do seu no início de uma palavra ):

grep -E '(^|[[:blank:]])<Hello'

ou com BRE:

grep '^\(.*[[:blank:]]\)\{0,1\}<Hello'
    
por 05.03.2013 / 11:30