Grep parece não encontrar todas as correspondências em um arquivo que eu espero

1

Não tenho certeza se não entendi completamente grep ou se regexes são a origem do meu problema, então tenho duas perguntas. Eu tenho um arquivo de teste simples chamado test.txt com o seguinte conteúdo:

$ cat test.txt Settings.xml blah Settings_1.xml blah Settings_2.xml

Quando executo grep em um diretório contendo apenas o arquivo de teste acima com o seguinte comando, ele retorna sem correspondência:

$ grep -ir "Settings*xml"

1) Por que o curinga * não captura o período?

E quando eu executo grep como tal:

$ grep -ir "Settings*.xml"

a única diferença é o período após o caractere curinga, os resultados são:

test.txt:Settings.xml

2) Por que grep não está encontrando as outras duas correspondências?

    
por Ben Sandeen 02.08.2017 / 19:01

2 respostas

3

O motivo é que * é um caractere especial em expressões regulares e significa %código%. Você tem que escapar zero or more preceding characters para significar um literal * character com * . Então, nos seus exemplos:

\

procuraria por uma string que comece com grep -ir "Settings*xml" e depois zero ou mais Setting caracteres e s no final. Não existe tal string no seu arquivo porque xml é sempre precedido por xml . E isso:

.

procuraria por uma string que comece com grep -ir "Settings*.xml" e depois zero ou mais Setting e s após zero ou mais .xml letras.

Seu primeiro regex corresponderia a algo assim:

s

    
por 02.08.2017 / 19:23
1

Esta outra resposta explica o que aconteceu, responde às suas perguntas explícitas. Minha resposta pretende introduzir um contexto mais amplo.

Eu suponho que você esperava que * correspondesse zero ou mais caracteres (qualquer caractere) e . significasse literalmente . . Isso funciona com o shell globbing, ou seja, se você tivesse arquivos assim:

$ ls -1
Settings.xml
blah
Settings_1.xml
Settings_2.xml

então (digamos, em bash ) você poderia fazer:

$ echo Settings*.xml
Settings.xml Settings_1.xml Settings_2.xml

Você não conseguiu o que esperava porque grep usa a sintaxe regex onde:

  • . corresponde (quase) a qualquer caractere,
  • * significa "zero ou mais caracteres precedentes",
  • \ força o próximo caractere a ser interpretado literalmente.

É por isso que em vez de "Settings*.xml" você deveria ter usado "Settings.*\.xml" . Neste caso:

  • .* faz o que você acha que * faria,
  • \. faz o que você acha que . faria.
por 03.08.2017 / 00:53