Eu observo o seguinte comportamento de grep ao executá-lo cinco vezes:

me@asus:~/go/src/company/topology-front$ lsof |grep "READ" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "README.md*" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "README.md" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "*README.md*" me@asus:~/go/src/company/topology-front$ lsof |grep "*README.md" me@asus:~/go/src/company/topology-front$ 

Não consegui entender por que as duas últimas tentativas de grep não estão retornando nenhum resultado .

Resposta

grep padrões são expressões regulares (também conhecidas como regex, regexp, RE), expressões regulares básicas (BRE), a menos que uma das -E / -F / -P / -K / -X opção (apenas as duas primeiras sendo padrão) é usada.

* é um operador regexp que corresponde a 0 ou mais do átomo anterior. Por exemplo, d* corresponde a 0 ou mais d s. Em BREs, quando no início do padrão ou ao seguir o

ou \( operadores regexp, ele corresponde apenas a * literal (também é usado literalmente dentro de [...] expressões de colchetes).

Portanto, grep "*README.md*" corresponde a linhas que contêm um seguido por README seguido por qualquer caractere único (o . operador regexp) seguido por m seguido por qualquer número de d s. Como qualquer número inclui 0, isso “é funcionalmente equivalente a grep "*README.m" (o que não faria diferença para quais linhas estão sendo correspondidas, apenas no que pode ser correspondido dentro da linha (que seria mostrado com a opção --color do GNU grep por exemplo)).

Por exemplo , corresponderia a essas 2 linhas:

*README mike ^^^^^^^^^ DONT***README-mddd ^^^^^^^^^^^^ 

(os ^ s mostrando o que dentro da linha é correspondido pela expressão regular, que você pode ver com --color)

Aqui, parece que você está confundindo expressões regulares com padrões de curinga do shell. O * operador curinga que corresponde a 0 ou mais caracteres pode ser escrito .* em expressões regulares. Mas fazer:

grep ".*README\.md.*" 

seria novamente o mesmo que:

grep "README\.md" 

Como grep procura uma correspondência dentro da linha em vez de encontrar linhas que correspondam exatamente ao padrão (para o qual você precisa -x).

Com ast-open grep, que também é ksh93 “s grep integrado (nem sempre integrado por padrão, e você precisa ativá-lo colocando /opt/ast/bin à frente de $PATH), você pode usar a opção -K para grep usar curingas shell (ksh93 estendidos). Com isso grep implementação, você pode fazer:

grep -K "README.md" 

ou

grep -xK "*README.md*" 

para corresponder em linhas que contêm README.md.

Com a mesma implementação, a correspondência de curinga também pode ser ativada em estendido (), aumentada (-X) ou semelhante a perl (-P) regular expressões com o operador (?K) (e \(?K\) em expressões regulares básicas que realmente quebram a conformidade com POSIX, então eu não confiaria nisso como pode ser removido em uma versão futura). Então você pode fazer:

grep -xE "(?K)*README.md*" 

lá.

Com qualquer implementação grep moderna, você também pode fazer:

grep -F README.md 

Para uma pesquisa de string fixa (onde . acima corresponde a um . em vez de qualquer caractere).

Comentários

  • FWIW: Perl reclama sobre * ou + no início do regex, e o mesmo acontece com grep -P
  • @ilkkachu , o mesmo acontece com grep -E com várias implementações. Aquele * tratado literalmente quando no início é especificado apenas para BREs. Com outros REs, YMMV.
  • @St é phaneChazelas eu não ' encontrei a especificação para o asterisco inicial . Está documentado em algum lugar? Eu ' m usando grep simples (ou grep -G) também.
  • @iBug, se você ler a resposta com mais cuidado, ' notará o que (eu acho) você ' referindo-se a is para ast-open ' s grep -K que usa padrões de shell (onde * corresponde a qualquer número de caracteres).
  • @iBug, se você quer dizer * não ser especial quando o primeiro caractere de um BRE, consulte a especificação POSIX

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *