別のサブディレクトリに同じ名前があるが拡張子が異なるファイルがない場合は、ファイルを削除するスクリプト

別のサブディレクトリに同じ名前があるが拡張子が異なるファイルがない場合は、ファイルを削除するスクリプト

ディレクトリ構造(下図)に一連のサムネイルとRAWファイルがあり、プレビュー画像をすばやく見て、不要なファイルを削除します。

RAWファイルは、各ディレクトリのRAWサブディレクトリにあります。

私が探しているのはbashコマンドですが、そのサムネイルがあるファイルがない場合はRAWファイルを削除する小さなスクリプトです。

サブディレクトリツリーは次のとおりです。

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

想像できるように、年と月のサブディレクトリが複数あり、時には大きなイベントが発生した場合は、月のサブディレクトリの下に一連のサブディレクトリがあります(下記参照)。したがって、理想的には、A content cron is run daily/を挿入しようとします。毎週作成したレビュー/変更を整理します。

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

答え1

はるかに簡単なCostas方式はスクリプトを必要としませんが、組み込み、正しいディレクトリ、および正しいコマンド置換を使用します。 (未検証)

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

これを行うには、bashスクリプト(いくつかのglobstar(**)といくつかの[[]]))を書くのは簡単です。これで作業は完了です!

答え2

テストされて動作しています。

#!/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

テスト:

]➬./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

スペースでテストします。

]➬./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

複数のディレクトリの場合:

 ]➬./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

他のソリューションで自由にテストしてみてください。最後の行のdeleteRAW呼び出しをコメントアウトします。

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

乾杯と幸運を祈ります。 :)

答え3

名前は同じですが、拡張子が異なる通信の場合

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

答え4

zshでは利用可能ですeグローバル予選ワイルドカードの一致をフィルタリングします。

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

関連情報