Eu quero procurar uma seqüência de texto em todos os arquivos em um diretório (e não em seus subdiretórios; sei que a -r
opção faz isso, mas não é isso que eu quero).
Corrida
grep "string" /path/to/dir
é suposto ser capaz de fazer isso, eu li, mas isso me dá o erro:
grep: dir: é um diretório
Em seguida, tentei executar
grep
em vários arquivos.grep "string" .bashrc .bash_aliases
funciona perfeitamente.grep "string" .bash*
funciona como pretendido também.grep "string" *
me dá os erros:grep: data: Is a directory grep: Desktop: Is a directory grep: Documents: Is a directory grep: Downloads: Is a directory ...
Apenas os erros são impressos, não recebo as linhas correspondentes. Eu tentei usar a -s
opção, mas sem sucesso.
Então, minhas perguntas:
Por que não consigo usar
grep
em um diretório, como em (1), quando devo fazê-lo? Eu já vi isso em vários exemplos na Internet.
Edit : Quando digo "usando grep em um diretório", quero dizer "pesquise em todos os arquivos desse diretório, exceto seus subdiretórios". Eu acredito que é isso que o grep faz quando você passa um diretório para ele no lugar de um arquivo. Estou incorreto?Por favor, me dê uma explicação sobre o funcionamento
grep
que explicaria o comportamento dos comandos em (2).
Editar : Deixe-me ser mais específico. Por que o uso de curingas para especificar vários arquivos para procurar trabalho com.bash*
e não com*
ou mesmo./*
?Como posso pesquisar todos os arquivos em um diretório (e não seus subdiretórios) usando
grep
?
*
, conhecido como globbing. Globbing não inclui nomes de arquivos que começam com um ponto.bashrc
como o padrão. Você pode definir opções de shell para incluir esses arquivos, mas poderá ficar um pouco confuso se não souber o que está fazendo. Um bom guia para a compreensão globing pode ser encontrada aqui mywiki.wooledge.org/globgrep "string" .bash*
.grep "string" * .* 2>/dev/null
ougrep -s "string" * .*
Respostas:
No Bash, um glob não se expandirá para arquivos ocultos; portanto, se você deseja pesquisar todos os arquivos em um diretório, especifique os arquivos ocultos
.*
e os não ocultos*
.Para evitar os erros "É um diretório", você pode usar
-d skip
, mas no meu sistema também recebo um errogrep: .gvfs: Permission denied
† , então sugiro usar-s
, que oculta todas as mensagens de erro.Portanto, o comando que você está procurando é:
Se você estiver pesquisando arquivos em outro diretório:
Outra opção é usar a
dotglob
opção shell, que fará com que um globo inclua arquivos ocultos.Para arquivos em outro diretório:
† Alguém mencionou que eu não deveria receber esse erro. Eles podem estar certos - eu li algumas coisas, mas não consegui entender nada disso.
fonte
*
e.*
?echo * .*
eecho *.*
execute em seu diretório pessoal, e a diferença deve ser óbvia. Caso contrário, LMK e eu vou explicar.echo *
mostra arquivos e pastasecho *.*
não ocultos,echo .*
mostra arquivos não ocultos, mostra todos os arquivos eecho * .*
mostra todos os arquivos e diretórios. Mas por que a razão do espaço entre os dois no último caso? Parece uma bagunça para mim. Não existe uma maneira de combinar os dois para obter os mesmos resultados? Ou então, existe uma explicação de sintaxe do porquê os dois precisam ser separados aqui, ou é* .*
um caso excepcional?*
representa todos os arquivos não ocultos (ou seja, nomes de arquivos que não começam com um ponto);.*
representa todos os arquivos escondidos (ou seja, nomes de arquivos que não começam com um ponto); e*.*
representa todos os arquivos não ocultos que contêm um ponto. Emecho * .*
, os dois globos devem estar separados porque são globos diferentes: um para não oculto, um para oculto. Embora, como escrevi na minha resposta, você possa*
incluir arquivos ocultos ativando adotglob
opção shell.*.*
é comum no Windows (DOS) como uma maneira de listar todos os arquivos, mas o * nix inclui apenas arquivos com um ponto, portanto, não faz sentido no * nix. Em vez disso, você usa*
para listar todos os arquivos, exceto arquivos ocultos, e.*
para listar arquivos ocultos.Você precisa da
-d skip
opção adicionada.O Grep está pesquisando dentro dos arquivos. Você pode pesquisar recursivamente, como você disse, se quiser pesquisar arquivos dentro de um diretório.
Por padrão, o grep lê todos os arquivos e detecta os diretórios. Como, por padrão, você não definiu o que fazer com os diretórios com a
-d
opção, ele fornece erro de saída.Pesquisando apenas dentro do diretório pai seria `grep -d skip" string "./*
fonte
man grep
.-d skip
não funciona; é basicamente o mesmo que-s
; veja também a edição. (c) Não,grep -d skip "string" ./*
também não funciona.Os veteranos provavelmente fariam isso:
fonte
find . -type f -exec grep string {} +
?-maxdepth 1
.find . -type f -maxdepth 1 -exec grep string /dev/null {} +
-H
para grep.Reformular - você deseja grep os arquivos em um nível de subdiretório, mas não recursa em todos os subdiretórios?
Ou se você não quiser os arquivos no diretório atual
Observe que isso não encontrará diretórios começando com um ponto.
deve fazer esse trabalho.
Há também
-maxdepth
e-mindepth
restrição parâmetros disponíveis para ofind
comando também.fonte
grep forthis */*
procuraria arquivos no diretório atual e em um diretório inativo?*/*
apenas combina as coisas com uma barra. Se você tivesse um arquivo nomeadoa/b
no diretório atual, `* / * corresponderia a isso.Aqui está um exemplo para ignorar diretórios sem ignorar todos os erros:
fonte