Excluindo um nome de diretório em um globus recursivo zsh

7

Estou executando o zsh no Linux em setopt extended_glob ksh_glob glob_dots . Estou procurando algo fácil de digitar na linha de comando, sem requisitos de portabilidade. Eu estou olhando para uma árvore de código-fonte, sem nomes de arquivos "estranhos" (por exemplo, sem \ em nomes de arquivos, nenhum nome de arquivo começando com - ).

Qualquer um dos seguintes comandos imprime a lista de subdiretórios do diretório atual recursivamente:

find -type d
print -l **/*/

Este é realmente um checkout do svn:

$ find -type d
./.deps
./.svn
./.svn/text-base
./.svn/prop-base
./.svn/tmp
./.svn/tmp/text-base
./.svn/tmp/prop-base
./.svn/tmp/props
./.svn/props
./lib/.svn
./lib/.svn/text-base
./lib/.svn/prop-base
./lib/.svn/tmp
./lib/.svn/tmp/text-base
./lib/.svn/tmp/prop-base
./lib/.svn/tmp/props
./src/.svn
./src/.svn/text-base
./src/.svn/prop-base
./src/.svn/tmp
./src/.svn/tmp/text-base
./src/.svn/tmp/prop-base
./src/.svn/tmp/props

Desejo excluir os diretórios .svn e seus subdiretórios que estão presentes em todos os diretórios. É fácil com find :

find -type d -name .svn -prune -o -print

Posso fazer isso com um short zsh glob? Ignorar arquivos de ponto chega perto (preciso explicitamente porque tenho glob_dots set):

print -l **/*(/^D)

Mas isso não é satisfatório porque esconde o diretório .deps , que eu quero ver. Eu posso filtrar os caminhos que contêm .svn :

print -l **/*~(*/|).svn(|/*)(/)

Mas isso é pouco mais curto que find (então, para que estou usando o zsh?). Eu posso encurtar isso para print -l **/*~*.svn*(/) , mas isso também filtra diretórios chamados hello.svn . Além disso, o zsh atravessa os diretórios .svn , o que é um pouco lento no NFS ou no Cygwin.

Existe uma maneira conveniente (como no fácil de digitar) de excluir um nome de diretório específico (ou melhor ainda: um padrão arbitrário) em uma globalização recursiva?

    
por Gilles 10.04.2013 / 01:46

2 respostas

19

Os operadores glob estendidos do Zsh suportam correspondência sobre / (ao contrário dos ksh, mesmo na implementação do zsh). O **/ de Zsh é um atalho para (*/)# ( */ repetido 0 ou mais vezes). Então, tudo o que preciso fazer é substituir * por ^.svn (qualquer coisa menos .svn ).

print -l (^.svn/)#

Limpo!

    
por 10.04.2013 / 02:16
2

Embora ksh93 globbing esteja longe de zsh mesmo com a opção globstar , em ksh93 , pode ser obtido com:

set -o globstar
FIGNORE='@(.|..|.svn)'
printf '%s\n' **/
    
por 10.04.2013 / 09:22