Comportamento estranho de “ls -a | grep ^ \. ”

10

Eu queria listar o conteúdo de um pwd e exibir apenas o arquivo começando com ponto. Eu tentei, ls -a | grep ^\.mas não consigo descobrir por que a saída contém também os arquivos que não começam com ponto. Por exemplo:

Pictures
.pip
.pki
.profile
projects
Public

Sei que posso conseguir o que quero, ls -ld .*apenas estou curioso sobre esse comportamento do grep que não consigo explicar.

ps-aux
fonte
Por que não apenas ls -d .*listar todos os arquivos começando .?
Barmar
Uma nota de advertência: nunca canalize a saída de ls para outro comando. Use find em vez disso. Tem muitas videossincrasias para serem confiáveis. Veja: Armadilha 1 em mywiki.wooledge.org/BashPitfalls - foi o número 1! O resto do site também é ótimo.
Joe

Respostas:

20

Cite o argumento para grep, assimls -a | grep '^\.'

A razão para isso é que o shell manipula \.e o transforma novamente em simples ., que grepentão trata como um curinga de um caractere. Em caso de dúvida, sempre cite uma sequência que contenha (ou possa conter) um caractere especial para o shell.

roaima
fonte
Por que o shell ignora \?
Ps-aux
\ é uma sequência de escape que faz com que o shell trate o seguinte caractere como literal. Nesse caso grep ^\\., \\ é tratado pelo shell como uma barra invertida única e novamente o grep trata a barra invertida única seguida pelo ponto como ponto literal.
Avinash Raj
11

Você precisa colocar o grep regex entre aspas.

ls -a | grep '^\.'

Nota: Não analise a saída do lscomando .

Avinash Raj
fonte
Por que é ruim analisar a saída de ls?
Ps-aux
No link: no modo padrão, se a saída padrão não for um terminal, o ls separa os nomes de arquivos com as novas linhas. Tudo bem até você ter um arquivo com uma nova linha em seu nome.
precisa
@ Michael Durrant: Eu sugeriria que permitir novas linhas nos nomes de arquivos é um erro grave do sistema.
Jamesqf #
@jamesqf - veja as novas linhas nos nomes de arquivos (especialmente a resposta do sml ).
don_crissti
0

Se você executar o cmd ls -a | grep ^ \. então grep não considera "\" como um caractere e significado especial de "." não se escape.

Quando usamos cmd ls -a | grep "^ \." então grep considera "\" como um caractere especial e significado de "." é escapado. Isso lhe dará um resultado conforme o esperado.

Se você deseja usar o grep cmd sem aspas, você deve também "" escapar do caractere. Você pode obter o resultado esperado sem aspas duplas seguindo o comando ls -a grep ^ \\.

Para detalhes sobre o significado de caracteres especiais no Regex, consulte o link a seguir. http://www.regular-expressions.info/quickstart.html

AVJ
fonte