다른 하위 디렉터리에 이름은 같지만 확장자가 다른 해당 파일이 없는 경우 파일을 삭제하는 스크립트

다른 하위 디렉터리에 이름은 같지만 확장자가 다른 해당 파일이 없는 경우 파일을 삭제하는 스크립트

디렉터리 구조(아래 표시)에 일련의 미리 보기 이미지와 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 ]]'\')

관련 정보