Remove o arquivo específico do diretório se for o único

5

Eu tenho muitos diretórios e subdiretórios. Eu quero recursivamente remover um arquivo específico de um diretório, se é o único lá. Suponha também que não haja subdiretórios nesse diretório. Então, para resumir, as suposições são:

  • O nome do arquivo é README.TXT (insensível a maiúsculas e minúsculas)
  • Não há outros arquivos ou diretórios no diretório em que o arquivo é encontrado

Estrutura:

 mkdir usecase
 cd usecase
 mkdir destroy_this
 touch destroy_this/readme.txt
 mkdir do_not_destroy_this
 touch do_not_destroy_this/readme.txt
 touch do_not_destroy_this/something-else.txt
 mkdir do_nothing
 cd do_nothing
 mkdir rm_this
 touch rm_this/README.TXT
 cd ..
 mkdir do_nothing_here
 cd do_nothing_here
 mkdir has_sub_dir
 touch README.TXT
 cd ..

A execução dos resultados acima resultaria nessa estrutura em árvore:

$ tree .
.
'-- usecase
    |-- destroy_this
    |   '-- readme.txt
    |-- do_not_destroy_this
    |   |-- readme.txt
    |   '-- something-else.txt
    |-- do_nothing
    |   '-- rm_this
    |       '-- README.TXT
    '-- do_nothing_here
        |-- has_sub_dir
        '-- README.TXT

Isso é o que eu tenho até agora:

find . -type f -iname "readme.txt" -exec sh -c 'ls $(dirname "{}") | wc -l' \;

A ideia é que eu conte o número de arquivos e diretórios e, se for um, remova o arquivo.

    
por raspi 31.05.2014 / 09:53

2 respostas

3

O que você tem é uma boa base para começar. Se você modificou o conteúdo do seu -exec , você poderia introduzir uma construção if/then que permitiria que você agisse no estado da contagem sendo 1 ou não.

$ find . -type f -iname "readme.txt" -exec \
    sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
        then echo "yes"; \
        else echo "no"; \
    fi' \;
no
yes
yes
no

Com isso, poderíamos expandir o comando echo "yes" para executar a remoção real do arquivo. Algo como rm "{}" deve fazer o truque.

Exemplo

$ find . -type f -iname "readme.txt" -exec \
    sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
        then echo "removing {}.."; rm "{}"; \
        else echo "no"; \
    fi' \;
no
removing ./usecase/destroy_this/readme.txt..
removing ./usecase/do_nothing/rm_this/README.TXT..
no

A execução da segunda vez confirma que os arquivos não estão mais lá:

$ find . -type f -iname "readme.txt" -exec \
    sh -c 'if [ "$(ls $(dirname "{}") | wc -l)" -eq "1" ]; \
        then echo "removing {}.."; rm "{}"; \
        else echo "no"; \
    fi' \;
no
no
    
por 31.05.2014 / 10:57
2
find . -type f -iname "readme.txt" -exec sh -c '
    for f do ls -1qap ${f%/*} | 
        grep -v "\(readme.txt\$\|/\$\|.\{1,2\}\$\)" &&
    echo rm "$f" ; done' \{\} +
    
por 31.05.2014 / 11:06