Encontre os diretórios “.git”, mas ignore alguns caminhos; ou como "encontrar -não" funciona

4

Não consigo descobrir como a localização não funciona.

Digamos que eu gostaria de localizar todos os diretórios .git na árvore.

find -type d -iname .git

Sem problemas, mas digamos que eu tenho alguns diretórios que não gosto de ser incluídos, em questão eles podem ser chamados de "antigos" e "backup".

Eu poderia canalizar para grep -v e isso funcionará bem.

find -type d -iname .git | grep -v old | grep -v backup

Mas, quando naveguei na man page para encontrar, percebi que não há, mas não consigo descobrir como ela deve funcionar.

Eu tentei assim, mas ele não exclui o antigo diretório.

find -type d -iname .git -not -iname old 

Como a localização não funciona? Posso usá-lo para encontrar esse problema?

    
por Johan 17.04.2014 / 07:11

4 respostas

2

encontrar tem um pouco de sofisticação para lidar com este caso:

If the expression contains no actions other than -prune, -print is performed on all files for which the expression is true.

Então, imprima explicitamente apenas as partes que você deseja:

find -type d \( -iname old -prune -o -iname backup -prune -o -iname .git -print \)

evita pesquisar as árvores antigas e de backup.

    
por 17.04.2014 / 08:21
2

Você pode excluir os diretórios especificando -path :

find . -type d \( -iname .git ! -path "*/old/*" ! -path "*/backup/*" \)

Observe que -not no GNU find é o mesmo que ! , mas não é compatível com POSIX.

Citações de man find :

   ! expr True  if  expr  is false.  This character will also usually need
          protection from interpretation by the shell.

   -not expr
          Same as ! expr, but not POSIX compliant.
    
por 17.04.2014 / 07:46
2

Você precisa da opção -prune de find , é realmente muito complicado. É necessário usar -path em vez de -name .

Eu acho que você quer usar isso:

find . -type d \( -path '*/old' -prune -o -iname '.git' -print \)

O efeito do -not é implementado por

  • correspondendo ao antigo "antigo" e o donig nada
  • ou (usando a opção -o)
  • correspondendo ".git" e imprimindo o nome
  • ou (por padrão)
  • não fazendo nada (porque a ação padrão normal de localizar, um -print implícito no final da linha de comando, está desabilitada, se -print já tiver sido usado)

Reconheço que outras variantes, embora pareçam mais complicadas na linha de comando, podem ser mais fáceis de usar, por exemplo, pelo uso de uma expressão lógica diferente e pela alteração da ação padrão.
Por outro lado, as variantes que envolvem -prune são mais fáceis de generalizar para casos mais complexos, quando outras sintaxes são difíceis de manipular apenas porque ficam muito longas para serem lidas.

    
por 17.04.2014 / 07:38
1
find -type d -iname .git -not -iname old 

Isso corresponde aos diretórios que são chamados de .git e não são chamados de old . Como um diretório chamado .git não pode ser chamado de old , a parte -not -iname old pode ser removida sem alterar o significado do comando.

-not diz "não combina", mas não "não recorre". Há uma maneira diferente de dizer "não recorrer": é uma ação chamada -prune . O comando a seguir significa "percorrer todos os diretórios recursivamente ( find ), mas parar em diretórios chamados old ( -iname old -prune ) e imprimir diretórios chamados .git ":

find -iname old -prune -o -type d -iname .git -print

Isso é analisado como ( -iname old -prune ) -o ( -type d -iname .git -print ) . Localizar é solicitado a procurar arquivos que atendam às condições -iname old ou ( -o ) -type d -iname .git . Quando um arquivo atende à primeira condição, a ação -prune (remoção da árvore percorrida, ou seja, não recurse) é executada. Quando um arquivo atende à segunda condição, a ação -print é executada. Como a impressão é a ação padrão, você pode omitir -print .

    
por 18.04.2014 / 03:30

Tags