Exclui todas as pastas vazias, mesmo com pastas .svn nele

6

Estou tentando excluir todas as pastas vazias em um diretório. No entanto, find . -type f -empty não encontra nada porque cada pasta contém uma pasta .svn oculta.

Como posso trabalhar com isso?

    
por atamanroman 25.02.2011 / 13:58

5 respostas

1

Se puder, você pode, claro, remover primeiro todas as pastas .svn . Desvantagem: você perderá informações de controle de versão, se alguém estiver usando o SVN. Se alguém estiver usando o SVN, então não é boa ideia apenas remover essas pastas (ou, na verdade, também é necessário removê-las do SVN, pois o SVN está rastreando pastas e arquivos).

Se isso não for possível, eu usaria a rota de script:

for folder in $(find . -type d); do
 if [ "'ls $folder | wc -l'" -eq 0 ]; then
  echo "I am going to delete $folder"
 fi
done

Primeiro, experimente o teste, porque pode haver algo surpreendente. Então você pode alterar rm -r em vez de echo .

Note, no entanto, isso removerá todas as pastas apenas com arquivos de pontos (assim, por exemplo, a/.this_is_super_important será excluído, se não houver outros arquivos ou pastas).

    
por 25.02.2011 / 14:18
3

Pequena modificação (simplesmente imprima o diretório e o pipe em xargs depois):

for folder in $(find -type d ! -path *.svn*); do
  if [ "'find $folder ! -path *.svn* ! -path $folder | wc -l'" -eq 0 ]; then
    echo $folder
  fi
done

Coloque isso em algum lugar no seu $PATH , talvez como svn-empties e, em seguida, execute primeiro:

svn-empties

para listar quais diretórios ele encontrou (modificar lista, se necessário) e, em seguida, canalizar para xargs :

svn-empties | xargs svn rm

Este script se tornou muito útil para mim ao usar git-svn (obrigado!). Como git não rastreia diretórios vazios, posso acabar com muitos diretórios vazios no repositório Subversion. Eu svn co uma cópia separada do repositório e execute svn-empties | xargs svn rm periodicamente. Usar o Subversion em primeiro lugar não foi minha decisão;)

    
por 22.10.2011 / 00:11
2

Eu apenas tropecei nisso e usei este script mas o modifiquei para considerar corretamente os diretórios vazios somente aqueles com .svn e nenhum outro arquivo, oculto ou normal.

Além disso, lembre-se de que estou usando o svn rm, então é suposto funcionar com um repositório, você pode adaptar o script para fazer algo diferente no diretório.

for folder in $(find -type d ! -path *.svn*); do
  if [ "'find $folder ! -path *.svn* ! -path $folder | wc -l'" -eq 0 ]; then
    svn rm $folder
  fi
done
    
por 29.04.2011 / 18:43
0

Para evitar problemas com espaço em branco, find e IFS magic (nomes de arquivos podem realmente conter novas linhas também, então IFS=$'\n' não é um marcador de prata), pode-se usar globs e arrays.

#!/bin/bash
search_dir=${1:-.}
shopt -s globstar dotglob
for svn_dir in "$search_dir"/**/.svn/; do
    base_dir=${svn_dir%/.svn/}
    base_dir_contents=("$base_dir"/*)
    if [ ${#base_dir_contents[@]} -eq 1 ]; then
        printf 'The directory "%s" only contains ".svn/".\n' "$base_dir"
    fi
done
  • O script usa um argumento de caminho opcional ou usa o caminho atual como padrão, se ausente.
  • globstar ativa o diretório percorrendo ** construct.
  • dotglob inclui arquivos ocultos em globos de asterisco.
  • O for glob deve ser seguro contra qualquer caractere de nome de diretório problemático. Globs sempre expandirão com segurança no Bash, o que não é o caso de ls , find , etc. A barra à direita garante que apenas correspondamos pastas chamadas .svn e não arquivos regulares (um caso de canto real, no entanto).
  • Os nomes dos arquivos contidos na pasta com o diretório .svn correspondente são colocados em uma matriz. Se o número de itens nessa matriz for 1 (ou seja, a pasta .svn que nós conhecemos por construção *), então é isso que estamos procurando.

Ele usa somente Bash built-ins e, portanto, deve ser mais rápido do que emitir garfos de sistema extras para find , mas a diferença provavelmente não é perceptível, e a E / S será o principal gargalo de qualquer maneira.

*: Sidenote menor (aplica-se também a outras soluções): existe uma possível condição de corrida se houver, por exemplo. somente o arquivo .svn e o foo em um diretório, e o diretório .svn é removido entre o for e o glob da matriz, o que resultaria em foo sendo removido também. No entanto, se alguém com intenção mal-intencionada tiver o privilégio de remover arquivos no sistema de arquivos, o jogo provavelmente já estará perdido e será mais fácil removê-los diretamente do que através de ataques de cronometragem.

Outra menção rápida é que as outras respostas devem citar as expansões *.svn* . Caso contrário, o comando find falhará se a pasta atual contiver um arquivo que corresponda a esse glob:

$ mkdir foo && cd foo
$ mkdir -p test1/.svn test2
$ find -type d ! -path *.svn*
.
./test1
./test2
$ touch foo.svnbar
$ find -type d ! -path *.svn*
.
./test1
./test1/.svn
./test2
$ find -type d ! -path "*.svn*"
.
./test1
./test2

Sem aspas, *.svn* será expandido prematuramente pelo shell para foo.svnbar .

    
por 29.03.2014 / 10:33
0
  1. resolveu o problema que: espaços no caminho
  2. pode chamar o script com o parâmetro PATH assim:

svn-empties YOU_WANT_TO_SEARCH_PATH

C_IFS=$IFS

IFS=$'\n'

for folder in $(find "$1" -depth -type d ! -path *.svn*|sort -r); do
  counts=$(find "$folder" -type f ! -path *.svn* ! -path $folder | wc -l)

  if [ $counts -eq 0 ]; then
    echo $folder
  fi

done

IFS=$C_IFS
    
por 29.03.2014 / 09:00