특정 하위 디렉토리가 비어있는 경우 상위 디렉토리 삭제 (비어 있지 않음)


11

특정 하위 디렉토리에 파일을 포함하는 모든 디렉토리를 유지해야하지만 하위 디렉토리가 비어있는 모든 디렉토리를 삭제해야합니다.

좀 더 구체적으로 설명하면 다음과 같습니다.

A
|
|--------312311
|       |
|       |----Recording
|       |----a.txt
|       |----b.txt
|
|
|--------453453
|       |----Recording
|                   |
|                   |-------a.mp3
|       |----a.txt
|       |----b.txt
|
|
|--------566532
|       |----Recording
|       |----a.txt
|       |----b.txt

하위 디렉토리는 파일을 포함하거나 포함하지 않을 수 있습니다. 따라서 '312311'및 '566532'와 같은 전체 디렉토리를 삭제해야하며 '453453'만 모든 데이터와 함께 남아 있어야합니다 .'Recording '폴더에 파일이 있기 때문에 특정 디렉토리입니다.

많은 게시물을 보았지만 많은 특정 파일 이름으로 연결됩니다. 일주일에 여러 번해야 할 일이 있으면 도움을 주시면 감사하겠습니다.


녹음은 항상 디렉토리의 첫 번째 레벨에 있습니까? 또한 : 모든 디렉토리가 기본 디렉토리 내부의 첫 번째 레벨에 있습니까?
Jacob Vlijm

A는 번호가 매겨진 디렉토리를 포함하는 최상위 디렉토리입니다. 그리고 번호가 매겨진 디렉토리에는 예를 들어 'Recording'폴더와 일부 'txt'파일이 들어 있습니다. 그리고 '녹음'에서 파일을 포함하거나 포함하지 않을 수 있습니다.
Derek James

당신은 당신의 텍스트의 그림을 제거하고 실제 텍스트를 질문에 넣을 것입니다. 텍스트 사진은 처리하기가 번거 롭습니다. 실제 텍스트를 사용하는 것이 다른 고유 편의 중에서도 훨씬 편리합니다.
LD James

난 당신에게 제임스 같은 질문을 했어요 ..
데릭 제임스

답변:


12

아래 스크립트는 설명대로 정확하게 작동합니다.

  1. 디렉토리 안의 폴더를 나열합니다
  2. 각 폴더 내부에서 "Recording"이라는 폴더를 찾습니다.

    • 존재 하고 비어 있으면 상위 폴더를 삭제합니다.
    • 존재 하지 않으면 상위 폴더도 삭제합니다.
    • A 내부의 첫 번째 레벨에있는 파일 은 삭제되지 않습니다.

이미지에서 :

A
|
|--------123456
|       |
|       |----Recording
|       |----a.txt
|       |----b.txt
|
|
|--------635623
|       |----Recording
|                   |
|                   |-------a.mp3
|       |----a.txt
|       |----b.txt
|
|
|--------123456
|       |----Recording
|       |----a.txt
|       |----b.txt
|
|--------Monkey.txt

결과 :

A
|
|
|--------635623
|       |----Recording
|                   |
|                   |-------a.mp3
|       |----a.txt
|       |----b.txt
|
|
|--------Monkey.txt

스크립트

#!/usr/bin/env python3
import os
import sys
import shutil

dr = sys.argv[1]

def path(*args):
    return os.path.join(*args)

for d in os.listdir(dr):
    try:
        if not os.listdir(path(dr, d, "Recording")):
            shutil.rmtree(path(dr,d))
    except FileNotFoundError:
        shutil.rmtree(path(dr,d))
    except NotADirectoryError:
        pass

사용

  1. 스크립트를 빈 파일로 복사하여 다른 이름으로 저장하십시오. delete_empty.py
  2. (full!) 디렉토리 (예 : 서브 디렉토리 포함, 예에서 A)를 다음 명령으로 인수로 실행하십시오.

    python3 /path/to/delete_empty.py /path/to/directory
    

그게 다야.

설명

폴더 "A"의 내용을 스크립트에 공급

os.listdir(dr)

하위 디렉토리 및 파일을 나열합니다. 그때:

if not os.listdir(path(dr, d, "Recording"))

각 (하위) 폴더의 내용을 나열하려고 시도합니다. 항목이 파일 인 경우 오류가 발생합니다.

except NotADirectoryError
    pass

또는 "레코딩"폴더가 전혀없는 경우 :

FileNotFoundError
    shutil.rmtree(path(dr,d))

"레코딩"폴더가 존재 하고 비어 있으면 상위 폴더가 제거됩니다.

if not os.listdir(path(dr, d, "Recording")):
    shutil.rmtree(path(dr,d))

편집하다

또한 주석에서 요청한대로 여러 하위 디렉토리 (이름)를 확인하는 버전입니다.

경우 디렉토리에 포함 된 모든 상장 (명사에 붙여서의 뜻을 나타냄 빈) 하위 디렉토리의 디렉토리가 유지됩니다. 그렇지 않으면 삭제됩니다.

사용

  1. 스크립트를 빈 파일로 복사하여 다른 이름으로 저장하십시오. delete_empty.py
  2. (full!) 디렉토리 (예 : 서브 디렉토리, 예제에 A 포함)와 서브 디렉토리 이름을 명령으로 인수로 실행하십시오.

    python3 /path/to/delete_empty.py /path/to/directory <subdir1> <subdir2> <subdir3>
    

그게 다야.

스크립트

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]; matches = sys.argv[2:]

def path(*args):
    return os.path.join(*args)

for d in os.listdir(dr):
    # delete directory *unless* either one of the listed subdirs has files
    keep = False
    # check for each of the listed subdirs(names)
    for name in matches:
        try:
            if os.listdir(path(dr, d, name)):
                keep = True
                break
        except NotADirectoryError:
            # if the item is not a dir, no use for other names to check
            keep = True
            break
        except FileNotFoundError:
            # if the name (subdir) does not exist, check for the next
            pass
    if not keep:
        # if there is no reason to keep --> delete
        shutil.rmtree(path(dr,d))

노트

먼저 테스트 디렉토리에서 실행하여 원하는대로 정확하게 수행하십시오.


이 코드는 실제로 도움이되었으며 말한대로 작동했습니다. 코드 주셔서 감사합니다. 정말 도움이됩니다.
Derek James

두 개 이상의 폴더를 유지하고 확인해야한다면이 코드에서 어떻게 할 수 있습니까? 'OR'또는 파이프 추가하기 | '어딘가에 .. 합계를 제안하십시오!
Derek James

약간의 수정 만 필요한 @DerekJames 안녕하세요. 오늘 오후에 게시하겠습니다.
Jacob Vlijm

경우 @Derek, 대기는 우수한 폴더를 제거해야 모든 폴더의 빈 또는 모든입니까? 하나의 우수한 디렉토리에 여러 개가있을 수 있습니까?
Jacob Vlijm

@Jacob, 'Recording'And 'Video'폴더가 두 개 있다고 가정합니다. 둘 다 확인해야합니다. 하위 폴더에 파일이 들어 있으면 폴더 '635623'이 삭제되지 않습니다. 또한 폴더를 추가하여 폴더를 추가 할 수 있는지 확인할 수 있습니다 ..
Derek James

11

사용 find하여 xargs:

find A -type d -name 'Recording' -empty -printf '%h\0' | xargs -0 echo rm -rf

( echo올바른 디렉토리를 식별하는 것이 편한 경우 제거하십시오 ). 이 printf '%h\0파트는 다음과 같이 (널로 종료 된) 상위 디렉토리를 인쇄합니다 man find.

       %h     Leading directories of file's name (all but the last ele‐
              ment).  If the file name contains no slashes (since it is
              in  the  current  directory)  the %h specifier expands to
              ".".

예 : 주어진

$ tree A
A
├── 312311
│   ├── a.txt
│   ├── b.txt
│   └── Recording
├── 453453
│   ├── a.txt
│   ├── b.txt
│   └── Recording
│       └── a.mp3
└── 566532
    ├── a.txt
    ├── b.txt
    └── Recording

6 directories, 7 files

그때

$ find A -type d -name 'Recording' -empty -printf '%h\0' | xargs -0 rm -rf
$ 
$ tree A
A
└── 453453
    ├── a.txt
    ├── b.txt
    └── Recording
        └── a.mp3

2 directories, 3 files

찾기 A-타입 d-이름 '레코딩'-빈 -printf '% h \ 0'| xargs -0 echo rm -rf 이것은 단지 "rm -rf"를 인쇄하고 A 형 d -name 'Recording'-empty -printf '% h \ 0'을 찾는 중입니다. | xargs -0 rm -rf가 작동하지 않습니다 ... 내가 뭔가 잘못하고
Derek James

@DerekJames A를 실제 디렉토리로 바꿔야합니다.
Jacob Vlijm

OP가 파일 이름에 숫자를 부여 했으므로 녹음 이름 대신 정규식을 입력해도 괜찮 [\d]*습니까?
George Udosen

@JacobVlijm : 실제 디렉토리로 바꾸었지만 여전히 wrking하지 않습니까?
Derek James

@DerekJames 이상하다! 내 시스템에서 작동했지만 먼저 디렉토리로 cd하는 것을 잊었을 수 있습니까? 기다림, 그건 중요하지 않습니다 ...
Jacob Vlijm

3

간단한 bash 솔루션은 다음과 같습니다.

for d in */; do rmdir "$d/Recording" && rm -r "$d"; done

때문에 작업 rmdir디렉토리가 비어 있지 않으면 실패하고 &&을 방지 rm -r하지 않으면 실행되는 rmdir성공합니다. glob */는 디렉토리에서만 작업하도록하므로 다른 파일에는 영향을 미치지 않습니다.


똑똑한 생각! +1
Jacob Vlijm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.