Entendendo o comando 'grep', mostra resultados diferentes do esperado [fechado]

0

Eu sou novo no Unix e estou tentando mostrar todos os arquivos (sem diretórios) no meu diretório, então eu uso o comando ls -p | grep -v / .

Ele me mostra uma lista parecida com esta:

Process1
Process2 
Process3
   ︙

Mas quando eu uso o comando ls -p | grep -v / | grep P* , ele mostra apenas alguns dos processos. Por que nem todos os processos são exibidos?

EDITAR

Eu percebi que usei o capital P em vez de minúsculas p. Isso é um erro.

    
por PanthersFan92 31.07.2016 / 12:40

2 respostas

3

Em seu segundo comando, você grep P* . Isso fará com que o shell faça globbing de nome de arquivo em P* , ou seja, ele expandirá P* para todos os arquivos que começam com a letra P .

Use set -x em seu shell para ver o que é executado (desativar o rastreio com set +x ). Eu realmente tenho o rastreamento ativado por padrão em minhas próprias sessões de shell interativas apenas para ver o que estou fazendo .

Apenas citar P* não resolverá isso, pois a expressão regular P* também corresponde a nomes de arquivos como APPLE e file.PP e, na verdade, hello_world.c e todos os outros nomes de arquivos, bem como P* , também correspondem a nomes de arquivos com não P s neles.

Geralmente, você não deve analisar a saída de ls , Portanto, o seguinte seria uma maneira melhor de obter uma lista de arquivos (não diretórios) começando com a letra P :

$ find . -type f -maxdepth 1 -name "P*"

Isso localizará todos os arquivos regulares ( -type f ) no diretório atual ( . ) com nomes começando com P ( -name "P*" ). A opção -maxdepth 1 restringe find apenas a este diretório. De outra forma, ele recursaria em subdiretórios também.

Para fazer com find o que você está fazendo com grep -v / , ou seja, removendo os diretórios da lista, em vez de selecionar os arquivos regulares:

$ find . ! -type d -maxdepth 1 -name "P*"

Isso também encontrará arquivos não regulares, como soquetes, etc. Em alguns shells, é necessário escapar ou citar o ! , ou seja, dizendo

$ find . "!" -type d -maxdepth 1 -name "P*"

ou

$ find . \! -type d -maxdepth 1 -name "P*"

Note que a citação de P* é importante para que seu shell não o expanda.

    
por 31.07.2016 / 12:48
3

O "P*" estaria correspondendo a algo (ou não ) do seu shell antes que o grep veja o parâmetro. Se você citar, obterá melhores resultados, mas lembre-se de que o grep corresponde a expressões regulares em vez de globs.

Então apenas um "P" funcionaria. Como é uma expressão regular, você não precisa do asterisco * para permitir que os caracteres após "P" sejam correspondidos (o grep os ignora por padrão):

ls -p | grep -v / | grep "P"

ou

ls -p | grep -v / | grep '^P'

Continuando com a questão alterada, para ignorar o caso, use a opção -i do grep, por exemplo,

ls -p | grep -v / | grep -i '^P'

Leitura adicional:

por 31.07.2016 / 12:45