Exclui recursivamente subdiretórios que não contêm padrão no OSX

1

Estou tentando excluir todos os subdiretórios (e arquivos internos) que não contêm um dos dois padrões no nome do diretório usando o Bash no OSX. Eu estou tentando fazer isso recursivamente - para um monte de diretórios pai.

Digamos que o padrão em sub dirs que eu quero não delete seja "foobar" ou "doobar"

Eu tenho um monte de diretórios pai, como este:

Parent001_dir
   001_boo
   002_hugs
   003_foobar
   004_doobar
   005_apple
   ...

Eu quero executar um código de loop para entrar em cada diretório pai e excluir as subdiretórios não correspondentes.

Código que achei que poderia funcionar:

for i in /path/to/parent/directories/
do
find !-name "*foobar*" -o !-name "*doobar*"  -delete
done

Mas eu li o manual de localização e não vejo nenhuma opção para não padrões de correspondência; ! -nome não é uma opção.

EDIT- de comentários, tentando:

find /path/to/parent/directories/ -type d -not -name "*foobar*" -not -name "*doobar*"  -delete

e recebendo uma mensagem "caminho potencialmente não seguro"

Se eu encontrar uma maneira de corrigir o meu código, eu poderia finalmente ter "Parent001_dir" e todos os outros diretórios parentes como: "

Parent001_dir
   003_foobar
   004_doobar

Existem caracteres curinga que podem consertar meu código? Ou devo usar outra abordagem inteiramente? Agradecemos antecipadamente por qualquer ajuda.

    
por Jordan Garner 02.10.2015 / 21:47

1 resposta

2

Primeiro de tudo, não há necessidade de um loop, find pode fazer tudo isso sozinho. Você pode negar condições usando os sinalizadores ! ou -not . Você também não quer -o , pois isso significa "localizar arquivos / pastas cujo nome não é foobar ou cujo nome não é doobar". Isso encontraria tudo desde que uma ou outra condição sempre será verdadeira ( foobar corresponde a "não doobar" e doobar corresponde a "não foobar"). O que você queria é algo como:

find /path/to/parent/dirs/* -type d ! -name "*foobar*" ! -name "*doobar*" -delete

ou

find /path/to/parent/dirs/* -type -d -not -name "*foobar*" -not -name "*doobar*" -delete

Você também pode, se desejar, fazer isso no shell. Por exemplo, com bash :

for i in /path/to/parent/dirs/*/; do 
    [[ "$i" =~ 'foobar' || "$i" =~ 'doobar' ]] || rm -rf "$i"; 
done

Não tenho certeza sobre os detalhes e não tenho um mac para testar isso, mas parece que o OSX não permite excluir diretórios. Eu acredito (mas não tenho certeza) que isso é o que este código faz :

/* Potentially unsafe - do not accept relative paths whatsoever */
if (strchr(entry->fts_accpath, '/') != NULL)
    errx(1, "-delete: %s: relative path potentially not safe",
        entry->fts_accpath);

Uma maneira de contornar isso é usar -exec :

find /path/to/parent/dirs/ -type d ! -name "*foobar*" ! -name "*doobar*"  \
    -exec rm -rf {} +

Todos esses comandos excluirão coisas. Teste-os antes de usar!

    
por 02.10.2015 / 22:29