Como apagar tudo dentro de um diretório, sem uma pasta específica e seu conteúdo

1

Minha estrutura de pastas é assim:

./build
./module/build
./source

Tudo o que quero manter é ./build e seu conteúdo.

O comando find . \! -path ./build -delete não exclui ./build , mas todo o seu conteúdo.

Como evitar isso?

    
por Sommereder 19.06.2017 / 11:53

5 respostas

1

Tente:

find . \! \( -wholename "./build/*" -o -wholename ./build \) -delete

Se você executar:

rm -rf /tmp/tmp2
mkdir /tmp/tmp2
cd /tmp/tmp2

mkdir -p build module/build source
touch .hidden build/abc build/abc2 source/def module/build/ghi

find . \! \( -wholename "./build/*" -o -wholename ./build \) -delete

find .

sua saída será:

./build
./build/abc

Isso é muito mais seguro do que tentar analisar a saída de ls , em que você precisa cuidar de nomes de arquivos ou diretórios com espaços ou, pior ainda, com novas linhas incorporadas, find manipula os corretamente.

    
por 19.06.2017 / 12:55
2

Aproveite o shell (bash) que você está usando:

shopt -s extglob
rm -rfvi ./!(build)
    
por 19.06.2017 / 12:20
0

Para expandir a resposta perfeita de Jimmij:

shopt -s extglob

Está carregando correspondência estendida de padrões no bash. De man bash :

If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized.  In  the  following
description, a pattern-list is a list of one or more patterns separated
by a |.  Composite patterns may be formed using  one  or  more  of  the
following sub-patterns:

      ?(pattern-list)
             Matches zero or one occurrence of the given patterns
      *(pattern-list)
             Matches zero or more occurrences of the given patterns
      +(pattern-list)
             Matches one or more occurrences of the given patterns
      @(pattern-list)
             Matches one of the given patterns
      !(pattern-list)
             Matches anything except one of the given patterns

Portanto:

rm -rfvi ./!(build)

É avaliado como excluir tudo, exceto esse padrão.

    
por 19.06.2017 / 14:08
0
find . -maxdepth 1 -mindepth 1 ! -name build -exec rm -rf {} \;

-maxdepth 1 só encontrará coisas na pasta atual, não em níveis mais profundos.

-mindepth 1 garantirá a exclusão de . da listagem de arquivos (que indica o diretório atual).

! -name build garantirá que nenhuma correspondência retorne com um nome exatamente correspondendo a 'compilação'. Então, se você tivesse uma pasta chamada 'build1', ela também seria removida se você executasse este comando.

-exec command {} \; executará o comando e passará o argumento diretamente para ele. Isso permite que nomes com espaços e caracteres ímpares funcionem também. O \; é necessário no final para que você descubra que chegou ao fim do comando que você passou.

Antes de executar o comando que realmente executará a exclusão, você deve executá-lo apenas para ter certeza:

find . -maxdepth 1 -mindepth 1 ! -name build -exec echo {} \;

Isto apenas fará eco a todos os nomes de arquivos e assegurará que a sintaxe esteja correta antes de você substituir o comando que deseja executar em cada item.

    
por 20.06.2017 / 09:16
0

find . \! -path ./build -do_something não atua em ./build , mas a percorre para corresponder aos arquivos contidos nela. Para informar que não percorra um diretório, passe a ação -prune .

find . -path ./build -prune -o . -o -delete

"Se o caminho completo for ./build , não o percorra, senão se for o diretório atual, não faça nada, caso contrário, exclua o arquivo."

    
por 21.06.2017 / 01:34

Tags