Como excluir determinadas pastas por caminho usando o comando “find” no Linux?

1

Eu tenho o seguinte em um diretório:

1/
2/
3/
4/
5/
active -> 1
previous -> 2

Essas são pastas, assim como dois links simbólicos apontando para uma pasta. Quero excluir todas as pastas que não estão sendo apontadas nos links simbólicos e não excluir os links simbólicos. Eu tentei o seguinte

find . -maxdepth 1 -mindepth 1 -type d -not -path "$(readlink -f active)" -not -path "$(readlink -f previous)"

Isso ainda retorna os dois diretórios que eu quero excluir. O que há de errado aqui?

    
por Blossoming_Flower 20.12.2017 / 17:55

3 respostas

1

Existem alguns problemas:

  1. readlink -f retorna um caminho absoluto, -path espera um relativo prefixado com ./ .
  2. Algumas versões de readlink retornam um caminho com uma barra final para um symlink, que é recusada por find (testado com o Ubuntu, não reproduzível no Gentoo).

Isso funcionou para mim no Ubuntu, mas pode não ser a solução mais elegante:

find . -maxdepth 1 -mindepth 1 -type d -not -path "./$(readlink active | sed "s/\/$//")" -not -path "./$(readlink previous | sed "s/\/$//")"

Aqui está uma alternativa um pouco mais simples usando realpath , testado no Gentoo; poderia ser o mais portátil:

find . -maxdepth 1 -mindepth 1 -type d -not -path "./$(realpath --relative-to=. active)" -not -path "./$(realpath --relative-to=. previous)"
    
por 20.12.2017 / 18:09
0

Como você já está usando alguns GNUisms ( -not , -mindepth , -maxdepth ), você pode fazer:

find -L . -mindepth 1 -maxdepth 1 -type d ! -xtype l \
  ! -samefile active ! -samefile previous

Então, você não precisaria depender dos destinos de links simbólicos estarem no formato correto ( ./1 se estiver usando find . , não 1 , nem ././1 nem /path/to/1 ) e escapar de caracteres curinga neles (se o symlink fosse para * , você precisaria de um -path './[*]' ).

Ou com zsh :

print -rl ./*(D/e:'[[ ! $REPLY -ef active && ! $REPLY -ef previous ]]':)
    
por 20.12.2017 / 22:10
-1

Por que não executar find apenas nos diretórios nos quais você está interessado, em vez de tentar filtrar os outros?

$ find ./active/ ./previous/

ou

$ find "./$(readlink active)" "./$(readlink previous)" -maxdepth 0
./1
./2

Ou se você quisesse que find correspondesse exatamente aos que os links simbólicos não apontam:

$ find . -mindepth 1 -maxdepth 1  -type d  -not -path "./$(readlink active)" -not -path "./$(readlink previous)"
./3
./4
./5
    
por 20.12.2017 / 21:04

Tags