Eu sei que este é um tópico antigo, mas me deparei com ele e pensei em compartilhar meu método, que descobri ser uma maneira muito rápida de usar find
para localizar apenas arquivos não binários:
find . -type f -exec grep -Iq . {} \; -print
A -I
opção de grep diz a ele para ignorar imediatamente os arquivos binários e a .
opção junto com o -q
fará com que ele corresponda imediatamente aos arquivos de texto, de forma que seja muito rápido. Você pode mudar o -print
para um -print0
para tubulações em xargs -0
ou algo se estiver preocupado com os espaços (obrigado pela dica, @ lucas.werkmeister!)
Além disso, o primeiro ponto só é necessário para certas versões do BSD find
, como no OS X, mas não atrapalha nada apenas tê-lo lá o tempo todo se você quiser colocar isso em um alias ou algo assim.
EDITAR : Como @ruslan corretamente apontou, o -and
pode ser omitido uma vez que está implícito.
find . -type f -exec grep -Il "" {} \;
.find -type f -exec grep -Iq . {} \; -and -print
que tem a vantagem de manter os arquivos armazenadosfind
; você pode substituir-print
por outro-exec
que só é executado para arquivos de texto. (Se você deixargrep
imprimir os nomes dos arquivos, não será possível distinguir os nomes dos arquivos com novas linhas neles.)find . -type f -exec grep -Il . {} +
é muito mais rápido. A desvantagem é que não pode ser estendido por outra pessoa,-exec
conforme sugeriu @ lucas.werkmeisterCom base nesta pergunta SO :
grep -rIl "needle text" my_folder
fonte
-I
é um salva-vidas.Por que não é prático? Se você precisa usá-lo com frequência e não deseja digitá-lo todas as vezes, basta definir uma função bash para ele:
coloque-o no seu
.bashrc
e depois execute:quando você quiser.
EDITAR para refletir a edição do OP:
se você quiser cortar as informações de mímica, pode simplesmente adicionar mais um estágio ao pipeline que filtra as informações de mímica. Isso deve fazer o truque, tomando apenas o que vem antes
:
:cut -d':' -f1
:fonte
file
manual: "Os usuários dependem de saber que todos os arquivos legíveis em um diretório têm a palavra 'texto' impressa."/proc/meminfo
,/proc/cpuinfo
etc. são arquivos de texto, masfile /proc/meminfo
diz/proc/meminfo: empty
. Eu me pergunto se 'vazio' deve ser testado além de 'texto', mas não tenho certeza se outros tipos podem relatar 'vazio'.Infelizmente, isso não é economia de espaço. Colocar isso no script bash torna isso um pouco mais fácil.
Este é um espaço seguro:
fonte
text.bin
? 2. E se um nome de arquivo contiver um:
?Outra maneira de fazer isso:
Se você quiser arquivos vazios também:
fonte
Que tal agora:
Se você quiser os nomes dos arquivos sem os tipos de arquivos, basta adicionar um
sed
filtro final .Você pode filtrar tipos de arquivo desnecessários adicionando mais
-e 'type'
opções ao últimogrep
comando.EDITAR:
Se sua
xargs
versão suportar a-d
opção, os comandos acima se tornarão mais simples:fonte
Veja como eu fiz ...
1 faça um pequeno script para testar se um arquivo é texto simples istext:
2 use encontrar como antes
fonte
== *"text"* ]]
?Tenho dois problemas com a resposta da histum:
Ele lista apenas arquivos de texto. Na verdade, ele não os pesquisa conforme solicitado. Para pesquisar, use
Ele gera um processo grep para cada arquivo, que é muito lento. A melhor solução é então
ou simplesmente
Isso leva apenas 0,2s em comparação com 4s para a solução acima (2,5 GB de dados / arquivos 7700), ou seja, 20x mais rápido .
Além disso, ninguém citou ag, o Silver Searcher ou ack-grep ¸as alternativas. Se um deles estiver disponível, eles são alternativas muito melhores:
Como última nota, tome cuidado com os falsos positivos (arquivos binários tomados como arquivos de texto). Eu já tinha falsos positivos usando grep / ag / ack, então é melhor listar os arquivos correspondentes antes de editar os arquivos.
fonte
Embora seja uma pergunta antiga, acho que as informações a seguir irão aumentar a qualidade das respostas aqui.
Ao ignorar arquivos com o conjunto de bits executáveis , apenas uso este comando:
Para evitar que ele recursivamente entre em outros diretórios:
Não há necessidade de tubos para misturar muitos comandos, apenas o poderoso comando simples find .
Dito isso, espero que isso seja útil para alguém.
fonte
Eu faço desta forma: 1) como há muitos arquivos (~ 30k) para pesquisar, eu gero a lista de arquivos de texto diariamente para uso via crontab usando o comando abaixo:
2) crie uma função em .bashrc:
Então posso usar o comando abaixo para fazer a pesquisa:
HTH :)
fonte
Eu prefiro xargs
se seus nomes de arquivo são estranhos, procure usando as opções -0:
fonte
grep eth0 $ (encontre / etc / -type f -exec arquivo {} \; | egrep -i "texto | ascii" | cut -d ':' -f1)
fonte
Esta é uma versão simplificada com explicação estendida para iniciantes como eu que estão tentando aprender como colocar mais de um comando em uma linha.
Se você escrevesse o problema em etapas, seria assim:
Para isso, podemos usar três comandos UNIX:
find
,file
, egrep
.find
irá verificar todos os arquivos no diretório.file
nos dará o tipo de arquivo. Em nosso caso, estamos procurando um retorno de 'texto ASCII'grep
irá procurar a palavra-chave 'ASCII' na saída defile
Então, como podemos amarrá-los em uma única linha? Existem várias maneiras de fazer isso, mas acho que fazê-lo na ordem de nosso pseudocódigo faz mais sentido (especialmente para um iniciante como eu).
find ./ -exec file {} ";" | grep 'ASCII'
Parece complicado, mas não é ruim quando o dividimos:
find ./
= examine cada arquivo neste diretório. Ofind
comando imprime o nome do arquivo de qualquer arquivo que corresponda à 'expressão', ou o que vier depois do caminho, que no nosso caso é o diretório atual ou./
A coisa mais importante a entender é que tudo após o primeiro bit será avaliado como verdadeiro ou falso. Se for True, o nome do arquivo será impresso. Se não, o comando segue em frente.
-exec
= este sinalizador é uma opção dentro do comando find que nos permite usar o resultado de algum outro comando como a expressão de pesquisa. É como chamar uma função dentro de uma função.file {}
= o comando sendo chamado dentro defind
. Ofile
comando retorna uma string que informa o tipo de arquivo de um arquivo. Regularmente, ele ficaria assim:file mytextfile.txt
. Em nosso caso, queremos que ele use qualquer arquivo que esteja sendo examinado pelofind
comando, então colocamos as chaves{}
para atuar como uma variável vazia ou parâmetro. Em outras palavras, estamos apenas pedindo que o sistema produza uma string para cada arquivo no diretório.";"
= isso é exigido porfind
e é a marca de pontuação no final do nosso-exec
comando. Consulte o manual para 'encontrar' para obter mais explicações se precisar executandoman find
.| grep 'ASCII'
=|
é um tubo. Pipe pega a saída de tudo o que está à esquerda e a usa como entrada para o que está à direita. Ele pega a saída dofind
comando (uma string que é o tipo de arquivo de um único arquivo) e a testa para ver se contém a string'ASCII'
. Em caso afirmativo, ele retorna verdadeiro.AGORA, a expressão à direita de
find ./
retornará verdadeiro quando ogrep
comando retornar verdadeiro. Voila.fonte
Se você estiver interessado em encontrar qualquer tipo de arquivo por seus bytes mágicos, usando o incrível
file
utilitário combinado com o poder dofind
, isso pode ser útil:Resultado:
Legenda:
$
é o prompt de shell interativo onde inserimos nossos comandosVocê pode modificar a parte depois
&&
de chamar algum outro script ou fazer outras coisas inline também, ou seja, se aquele arquivo contém uma determinada string, procure o arquivo inteiro ou procure por uma string secundária nele.Explicação:
find
itens que são arquivosxargs
alimentar cada item como uma linha em umbash
comando / script do linerfile
verifica o tipo de arquivo por byte mágico,grep
verifica se ASCII existe, em caso afirmativo, após&&
a execução do próximo comando.find
imprime os resultadosnull
separados, isso é bom para evitar nomes de arquivos com espaços e metacaracteres.xargs
, usando a-0
opção, lê-osnull
separadamente,-I @@
pega cada registro e usa como parâmetro / args posicional para o script bash.--
poisbash
garante que tudo o que vier depois é um argumento mesmo que comece com-
like, o-c
que poderia ser interpretado como uma opção bashSe você precisar encontrar tipos diferentes de ASCII, simplesmente substitua
grep ASCII
por outro tipo, comogrep "PDF document, version 1.4"
fonte
Use o comando find para listar todos os arquivos, use o comando file para verificar se são texto (não tar, chave), finalmente use o comando awk para filtrar e imprimir o resultado.
fonte
Que tal agora
fonte
"needle text"
"needl text"
"needle text"
seria encontrado