O que eu achei confuso -prune
é que é uma ação (como -print
), não um teste (como -name
). Ele altera a lista "tarefas", mas sempre retorna verdadeiro .
O padrão geral de uso -prune
é o seguinte:
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
Você quase sempre deseja o -o
(OR lógico) imediatamente após -prune
, porque a primeira parte do teste (até e inclusive -prune
) retornará falso para o que você realmente deseja (ou seja: o que você não quer remover).
Aqui está um exemplo:
find . -name .snapshot -prune -o -name '*.foo' -print
Isso encontrará os arquivos "* .foo" que não estão nos diretórios ".snapshot". Neste exemplo, -name .snapshot
compõe o [conditions to prune]
, e -name '*.foo' -print
é [your usual conditions]
e [actions to perform]
.
Notas importantes :
Se tudo o que você deseja fazer é imprimir os resultados, você pode estar acostumado a deixar de fora a -print
ação. Você geralmente não quer fazer isso ao usar -prune
.
O comportamento padrão de localização é "e" a expressão inteira com a -print
ação se não houver outras ações além de -prune
(ironicamente) no final. Isso significa que escrever isso:
find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
é equivalente a escrever isso:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
o que significa que também imprimirá o nome do diretório que você está removendo, o que geralmente não é o que você deseja. Em vez disso, é melhor especificar explicitamente a -print
ação, se é isso que você deseja:
find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
Se a sua "condição usual" corresponder a arquivos que também correspondem à sua condição de remoção, esses arquivos não serão incluídos na saída. A maneira de corrigir isso é adicionar um -type d
predicado à sua condição de remoção.
Por exemplo, suponha que desejássemos remover qualquer diretório que começou com .git
(isso é admitido de certa forma artificial - normalmente você só precisa remover a coisa com o nome exato .git
), mas que não fosse isso, queria ver todos os arquivos, incluindo arquivos como .gitignore
. Você pode tentar o seguinte:
find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
Isso não incluiria .gitignore
na saída. Aqui está a versão fixa:
find . -name '.git*' -type d -prune -o -type f -print # DO THIS
Dica extra: se você estiver usando a versão GNU do find
, a página texinfo para find
tem uma explicação mais detalhada do que sua página de manual (como é verdade para a maioria dos utilitários GNU).
-prune
não funciona apenas em diretórios (mas, para diretórios, também impede a inserção de diretórios correspondentes a essa condição, ou seja, aqui os diretórios correspondentes a essa-name .snapshot
).-prune
ele mesmo que causa isso, a propósito. A questão é que o operador ou "curto-circuito" e / ou tem precedência menor que e. O resultado final é que, se um arquivo chamado.snapshot
for encontrado, ele corresponderá ao primeiro-name
,-prune
não fará nada (mas retornará verdadeiro) e, em seguida, o ou retornará verdadeiro, pois o argumento esquerdo era verdadeiro. A ação (por exemplo-print
:) faz parte de seu segundo argumento, portanto nunca tem uma chance de ser executada.-print
no final, agora eu posso parar de adicionar\! -path <pattern>
além-prune
Normalmente, a maneira nativa em que fazemos as coisas no linux e a maneira como pensamos é da esquerda para a direita.
Então, você escreveria o que procurava primeiro:
Então você provavelmente clica em enter e percebe que está obtendo muitos arquivos de diretórios que não deseja. Vamos excluir / media para evitar procurar nas unidades montadas.
Agora você deve apenas ANEXAR o seguinte ao comando anterior:
então o comando final é:
............... | <--- Incluir ---> | .................... | <- -------- Excluir ---------> |
Eu acho que essa estrutura é muito mais fácil e se correlaciona com a abordagem correta
fonte
find
é inteligente o suficiente para processar a-prune
cláusula primeiro. Hummm, interessante.-prune
partir de agora./media
, notando que não é chamado*.php
e depois verificando se está atualmente dentro/media
, vendo que está e, portanto, pulando toda a subárvore inteira. Ainda é da esquerda para a direita, não faz diferença desde que as duas verificações não se sobreponham.Cuidado que -prune não impede a descida em nenhum diretório, como alguns já disseram. Impede a descida em diretórios que correspondem ao teste ao qual é aplicado. Talvez alguns exemplos ajudem (veja a parte inferior para um exemplo de regex). Desculpe por isso ser tão demorado.
fonte
find . -name test -prune -o -print
: iow,-prune
é uma ação que também trabalha em arquivosAdicionando ao conselho dado em outras respostas (não tenho representante para criar respostas) ...
Ao combinar
-prune
com outras expressões, há uma diferença sutil no comportamento, dependendo de quais outras expressões são usadas.O exemplo do @Laurence Gonsalves encontrará os arquivos "* .foo" que não estão nos diretórios ".snapshot": -
No entanto, essa mão curta ligeiramente diferente irá, talvez inadvertidamente, também listar o
.snapshot
diretório (e qualquer diretório .snapshot aninhado): -O motivo é (de acordo com a página de manual no meu sistema): -
Ou seja, o segundo exemplo é o equivalente a inserir o seguinte, modificando assim o agrupamento de termos: -
Isso foi observado pelo menos no Solaris 5.10. Tendo usado vários sabores do * nix por aproximadamente 10 anos, só recentemente procurei uma razão pela qual isso ocorre.
fonte
-prune
com e sem-print
!A remoção é uma não recursão em nenhuma alternância de diretório.
Na página do manual
Basicamente, ele não será incluído em nenhum subdiretório.
Veja este exemplo:
Você tem os seguintes diretórios
Se você executar
find -name test2
:Ele retornará os dois diretórios
Se você executar
find -name test2 -prune
:Ele retornará apenas / home / test2, pois não descerá em / home / test2 para encontrar / home / test2 / test2
fonte
Não sou especialista nisso (e esta página foi muito útil junto com http://mywiki.wooledge.org/UsingFind )
O que acabamos de notar
-path
é para um caminho que corresponde totalmente à string / caminho que vem logo depoisfind
(.
nesses exemplos), onde as-name
corresponde a todos os nomes de base.bloqueia o diretório .git no seu diretório atual ( como encontrado em
.
)bloqueia todos os subdiretórios .git recursivamente.
Observe o
./
é extremamente importante !!-path
deve corresponder a um caminho ancorado.
ou o que vier logo após a localização, se você conseguir correspondências sem ele (do outro lado do ou '-o
'), provavelmente não sendo podado! Eu era ingenuamente inconsciente disso e me pôs a usar -path quando é ótimo quando você não deseja remover todos os subdiretórios com o mesmo nome de base: Dfonte
find bla/
então você precisaria -caminhobla/
.git (ou se você empurrou um*
na frente em vez disso, iria se comportar mais como -nome)Mostre tudo, incluindo o próprio diretório, mas não o conteúdo longo e chato:
fonte
Se você ler todas as boas respostas aqui, meu entendimento agora é que todos os seguintes retornam os mesmos resultados:
Mas o último levará muito mais tempo, pois ainda pesquisa tudo no diretório1. Acho que a verdadeira questão é como obter
-or
resultados indesejados sem realmente procurá-los.Acho que podar significa não fazer partidas passadas decentes, mas marcar como concluídas ...
http://www.gnu.org/software/findutils/manual/html_mono/find.html "No entanto, isso não se deve ao efeito da ação '-prune' (que impede apenas descidas adicionais, não garante ignoramos esse item.) Em vez disso, esse efeito se deve ao uso de '-o'. Como o lado esquerdo da condição “ou” foi bem-sucedido em ./src/emacs, não é necessário avaliar a lado da mão ('-print') para este arquivo em particular. "
fonte
find
cria uma lista de arquivos. Aplica o predicado que você forneceu a cada um e retorna aqueles que passam.Essa ideia que
-prune
significa excluir dos resultados foi realmente confusa para mim. Você pode excluir um arquivo sem remoção:Tudo o que
-prune
faz é alterar o comportamento da pesquisa. Se a correspondência atual for um diretório, ele diz "eifind
, aquele arquivo que você acabou de corresponder, não desce nele" . Apenas remove essa árvore (mas não o próprio arquivo) da lista de arquivos a serem pesquisados.Deve ser nomeado
-dont-descend
.fonte
Existem algumas respostas; alguns deles são muito teóricos. Vou deixar por que precisei remover uma vez, então talvez o tipo de explicação sobre necessidade / primeiro exemplo seja útil para alguém :)
Problema
Eu tinha uma pasta com cerca de 20 diretórios de nós, cada um com seu
node_modules
diretório conforme o esperado.Depois de entrar em qualquer projeto, você vê cada um
../node_modules/module
. Mas você sabe como é. Quase todos os módulos têm dependências, então o que você está vendo é mais parecido comprojectN/node_modules/moduleX/node_modules/moduleZ...
Eu não queria me afogar com uma lista com a dependência da dependência de ...
Conhecer
-d n
/-depth n
, isso não teria me ajudado, pois o diretório principal / primeiro node_modules que eu queria de cada projeto estava em uma profundidade diferente, assim:Como posso obter a primeira lista de caminhos que terminam na primeira
node_modules
e passar para o próximo projeto para obter a mesma?Entrar
-prune
Ao adicionar
-prune
, você ainda terá uma pesquisa recursiva padrão. Cada "caminho" é analisado, e todo achado é cuspido efind
continua cavando como um bom sujeito. Mas é a busca por mais donode_modules
que eu não queria.Portanto, a diferença é que, em qualquer um desses caminhos diferentes,
-prune
seráfind
necessário parar de ir mais longe nessa avenida em particular quando encontrar o item. No meu caso, anode_modules
pasta.fonte