Como o -name muda para o GNU encontrar trabalho ao direcionar um diretório e seu conteúdo?

1

Eu tenho uma pasta cheia de arquivos de origem para um aplicativo, o projeto usa o git para controle de versão e, portanto, há um diretório .git :

├── composer.json
├── .git
│   ├── branches
│   ├── config
│   ├── info
│   ├── logs
│   ├── objects
│   ├── packed-refs
│   └── refs
├── .gitignore
├── Gruntfile.js
├── less
│   ├── framework
│   ├── index.less
│   └── view_specific.less
├── package.json
[...]

Eu regularmente preciso fazer algo com todos os arquivos de origem enquanto ignoro os arquivos de controle de versão, ou seja, o diretório .git e tudo o que está sob ele.
Normalmente, uso a opção -not -path para find para excluir um diretório, por exemplo,

find . -not -path "*git*" 

o problema com isto é que é muito amplo, por ex. ele excluirá o arquivo .gitignore e quaisquer outros arquivos que tenham git , por exemplo, agitar , fugitivo etc.
Descobri que find com a opção -name e -prune parece segmentar o diretório .git e seu conteúdo:

% find . -name ".git" -prune -o -print | grep git
./.gitignore

mas não entendo como -name está correspondendo aos nomes dos arquivos.
De man find

   -name pattern
      Base  of  file  name (the path with the leading directories removed) matches shell pattern pattern.  

Para mim, isso significa que -name corresponde apenas quando o padrão corresponde ao último segmento em um nome de arquivo, por exemplo, -name foo corresponderia a /dir1/dir2/foo , mas não /dir1/dir2/foo/dir3/dir4/some_file para mim, o ponto inteiro de -path era a correspondência de padrões como foo para arquivos com nomes de caminho como /dir1/dir2/foo/dir3/dir4/some_file .
Parece que -name pode corresponder a qualquer segmento no caminho de arquivo - não apenas ao último segmento - desde que seja uma correspondência completa com o segmento dentro das barras?
Caso contrário, como -name combina nomes de arquivos?

    
por the_velour_fog 27.06.2016 / 13:59

2 respostas

1

Para ignorar os diretórios .git e tudo abaixo deles, você precisa de um constructo como este

find . \( -name '.git' -prune \) -o \( -print {or whatever else you want to do} \)

Isso diz a find que quando encontra um arquivo ou diretório chamado .git é para podar sua árvore e não descer mais abaixo nesse caminho. Tudo o mais pode ser combinado - e processado - dentro da outra metade da condição ou .

(As barras invertidas nos parênteses as impedem de serem processadas pelo shell e, para esse exemplo simplista, são tecnicamente desnecessárias. Deixei-as explicando como e e ou constrói bind.)

Agora, considere sua preocupação com uma pasta chamada foo :

e.g. -name foo would match /dir1/dir2/foo but not /dir1/dir2/foo/dir3/dir4/some_file

Você está correto, mas acho que perdeu o corolário. Em algum momento, find alcançará /dir1/dir2/foo . O -name foo corresponderá e então o -prune será invocado. find não pode alcançar abaixo de foo sem primeiro ver foo .

Consequentemente, /dir1/dir2/foo/dir3/dir4/some_file nunca pode ser alcançado.

O resultado inicial da inspeção é que, de alguma forma, -name foo corresponde a /dir1/dir2/foo/dir3/dir4/some_file , mas, na verdade, corresponde a /dir1/dir2/foo e abandonou qualquer inspeção adicional dessa árvore.

Em contraste com -name foo , que corresponde a foo apenas como o último componente de um caminho, -path foo corresponderá apenas se foo for um caminho completo. ( find * -path foo pode corresponder a foo no nível superior, mas find . -path foo nunca pôde corresponder a ./foo .)

    
por 27.06.2016 / 14:48
1

Seu entendimento de -name está correto. Apenas coincide com o nome do arquivo; o caminho que leva ao arquivo (a cadeia de diretórios contendo) é irrelevante.

O que você está perdendo é o efeito de -prune . Contraste

find . -name ".git" -o -print 

que significa "se for chamado .git , então não faça nada, senão imprima o caminho e recrute nele se for um diretório" com

find . -name ".git" -prune -o -print 

que significa “se for chamado de .git , então não recorra a ele , senão imprima o caminho e recorra a ele se for um diretório”.

    
por 28.06.2016 / 03:05

Tags