script para excluir arquivos se não houver nenhum arquivo correspondente com o mesmo nome, mas uma extensão diferente em outro subdiretório

1

Eu tenho uma série de imagens de visualização e arquivos RAW em uma estrutura de diretórios (mostrada abaixo), eu reviso rapidamente as imagens de visualização e excluo aquelas que não quero.

Os arquivos RAW estão em um subdiretório RAW de cada diretório.

O que estou procurando é um comando bash ou um script pequeno que excluirá o arquivo RAW, se um arquivo com a imagem de visualização correspondente não existir.

A árvore subdirecional parece:

2016/
     05/
        image1.jpg
        image2.jpg
        image3.jpg
        RAW/
            image1.RAW
            image2.RAW
            image3.RAW

Como você pode imaginar, há vários subdiretórios de ano e mês, ocasionalmente, se houver um evento grande, pode haver um conjunto adicional de subdiretórios abaixo do subdiretório do mês (como mostrado abaixo). Então, idealmente, estou procurando algo que pode entrar no cron para rodar uma vez por dia / semana para limpar depois de qualquer revisão / alteração que eu faça.

2016/
     05/
        image1.jpg
        image2.jpg
        image3.jpg
        RAW/
            image1.RAW
            image2.RAW
            image3.RAW
        event 1/
                image4.jpg
                image5.jpg
                image6.jpg
                RAW/
                    image4.RAW
                    image5.RAW
                    image6.RAW
        event 2/
                image7.jpg
                image8.jpg
                image9.jpg
                RAW/
                    image7.RAW
                    image8.RAW
                    image9.RAW
    
por camerafilehandler 17.06.2016 / 19:29

4 respostas

2

O mais fácil será o caminho Costas sem qualquer script, mas usando builtin, dir apropriado e substituição de comando adequada. (não testado)

find 2016 -name '*.RAW' -execdir sh -c '[ ! -f "../${0%.RAW}.jpg" ]' {} \; -delete

Escrever um script bash fazendo isso é trivial, alguns globstar (**) e alguns [[]] e feitos!

    
por 18.06.2016 / 20:49
1

Testado e funcionando.

#!/usr/bin/env bash
#delete RAW if Preview img doesn't exists

createTest() {
  local dir=$1
  rm -rf "$dir"
  mkdir -p "$dir"/05/{"event 1","event 2"}/RAW/
  mkdir -p "$dir"/05/RAW
  touch "$dir"/05/RAW/image{1..3}.RAW; touch "$dir"/05/image{1..2}.jpg
  touch "$dir/05/event 1/RAW/"image{4..6}.RAW; touch "$dir/05/event 1/"image{4..5}.jpg
  touch "$dir/05/event 2/RAW/"image{7..9}.RAW; touch "$dir/05/event 2/"image{7..8}.jpg
}

deleteRAW() {
  local jpg= 
  local t=
  shopt -s globstar; 
  for raw in "$1"/**/*.RAW; do 
    t=${raw##*/}
    jpg=${raw%/*}/../${t%.*}.jpg
    if [[ ! -f $jpg ]]; then
      rm -f "$raw"
      echo "Removed $raw"
    fi
  done;
}

for dir; do
   createTest "$dir"
   deleteRAW "$dir"
done

Teste:

]➬./delete.sh 2016
Removed 2016/05/RAW/image3.RAW
Removed 2016/05/event 1/RAW/image6.RAW
Removed 2016/05/event 2/RAW/image9.RAW

Teste com espaços:

]➬./delete.sh "2016 spaces"
Removed 2016 spaces/05/RAW/image3.RAW
Removed 2016 spaces/05/event 1/RAW/image6.RAW
Removed 2016 spaces/05/event 2/RAW/image9.RAW

com vários dirs:

 ]➬./delete.sh "2016 spaces" 2017
 Removed 2016 spaces/05/RAW/image3.RAW
 Removed 2016 spaces/05/event 1/RAW/image6.RAW
 Removed 2016 spaces/05/event 2/RAW/image9.RAW
 Removed 2017/05/RAW/image3.RAW
 Removed 2017/05/event 1/RAW/image6.RAW
 Removed 2017/05/event 2/RAW/image9.RAW

Você pode se sentir livre para testá-lo usando outras soluções comentando a chamada deleteRAW na última linha.

for dir; do
   createTest "$dir"
   #deleteRAW "$dir"      
done

Felicidades e melhor sorte. :)

    
por 19.06.2016 / 12:45
1

Se a correspondência for baseada nos mesmos nomes, mas em extensões diferentes

find 2016 -name '*.RAW' -exec bash -c '[ ! -f "${0//RAW/}jpg" ]' {} \; -delete
    
por 17.06.2016 / 20:21
1

Em zsh, você pode usar o e qualifier para filtrar o curinga correspondências.

rm **/*.RAW(e\''[[ ! -e ${REPLY//\/RAW\//\/}:r.jpg ]]'\')
    
por 19.06.2016 / 01:28