grep comando com ls -a não está funcionando corretamente?

1

Eu estava tentando listar alguns arquivos ocultos no meu diretório pessoal e encontrei um comportamento muito estranho do comando grep ao combinar com o comando ls .

  1. Eu executei ls -a no meu diretório inicial e obtive todos os arquivos incluindo arquivos ocultos conforme o esperado.
  2. Eu queria listar todos os arquivos ocultos começando com 'xau', então executei ls -a |grep -i .xau* e ele também funcionou como esperado.
  3. Em seguida, executei ls -a |grep -i .x* no mesmo diretório, mas não listou nada .
  4. Eu digitei ls -a |grep -i .*x por engano (note que este caractere curinga * e o caractere 'x' mudaram de lugar) e o interessante é que ele se comportou como o que eu pretendia no passo 3. Eu tentei a mesma coisa com este comando ls -a .*x e ls -a .*X mas eu recebo nenhum erro de arquivo ou diretório .

Euadicioneiasaídadetextoreal aqui

Alguns de vocês podem perguntar por que não usam apenas ls -a .x* , mas a coisa com grep é que ela imprime com as cores apropriadas. Então alguém poderia me explicar isso?

    
por Doe McBond 09.10.2016 / 13:25

2 respostas

4

Você está sofrendo de expansão prematura do glob.

.xa* não se expande porque não corresponde a nada no diretório atual. (Globs diferenciam maiúsculas e minúsculas.) No entanto, .x* faz corresponder alguns arquivos, portanto, isso é expandido pelo shell antes de grep vê-lo.

Quando grep recebe vários argumentos, assume que o primeiro é o padrão e o restante são arquivos para procurar esse padrão.

Portanto, no comando ls -a | grep -i .x* , a saída de ls é ignorada , e o arquivo ".xsession-errors.old" é pesquisado pelo padrão ".xsession-errors" . Não é de surpreender que nada seja encontrado.

Para evitar isso, coloque seus caracteres especiais entre aspas simples ou duplas. Por exemplo:

ls -a | grep -i '.x*'

Você também está sofrendo de regex vs. glob confusion.

Você parece estar procurando por arquivos que iniciam com a cadeia literal ".x" e são seguidos por qualquer coisa - mas as expressões regulares não funcionam da mesma maneira que as globs de arquivo. O * em regex significa "o caractere precedente zero ou mais vezes", e não "qualquer seqüência de caracteres", como acontece em globs de arquivos. Então o que você provavelmente quer é:

ls -a | grep -i '^\.x'

Isso procura por arquivos cujos nomes iniciem com os caracteres literais ".x" ou ".X". Na verdade, como há apenas uma letra que você está especificando, você pode facilmente usar uma classe de caracteres em vez de -i :

ls -a | grep '^\.[xX]'

A questão é que as expressões regulares são muito diferentes das globs de arquivos.

Se você apenas tentar ls -a | grep -i '.x*' , como foi sugerido, ficará surpreso ao ver que TODOS os arquivos serão exibidos! (A mesma saída que ls -a diretamente, exceto colocada em linhas separadas como em ls -a -1 .)

Como assim?

Bem, em regex (mas não em globs de shell), um ponto ( . ) significa "qualquer caractere único". E um asterisco ( * ) significa "zero ou mais do caractere precedente". Assim, o regex .x* significa "qualquer caractere, seguido por zero ou mais instâncias do caractere 'x'."

Naturalmente, você não tem permissão para ter nomes de arquivo nulos, então todo nome do arquivo contém "um caractere seguido por pelo menos zero 'x'." :)

Resumo:

Para obter os resultados desejados, você precisa entender duas coisas:

  1. Caracteres glob especiais não listados (incluindo * , ? , [] e alguns outros) serão expandidos pelo shell antes do comando que você está executando sempre vê em> eles, e
  2. Expressões regulares são diferentes (e mais poderosas que) globs de arquivos.
por 09.10.2016 / 13:38
1

O problema é que você não coloca * entre aspas e faz o shell expandi-lo antes de executar um comando. Veja:

$ touch .xau1 .xau2
# this won't work
$ ls -a | grep -i .xau*
# but this does
$ ls -a | grep -i ".xau*"
.xau1
.xau2
# this one too
$ ls -a | grep -i '.xau*'
.xau1
.xau2
# check what shell sees
$ ls -a | grep -i .xau* # now don't press enter but C-x * and you'll see this:
$ ls -a | grep -i .xau1 .xau2
    
por 09.10.2016 / 13:36

Tags