यदि विशिष्ट चाइल्ड डायरेक्टरी खाली है, तो पेरेंट डायरेक्टरी (गैर-खाली) को हटाएं


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 'को इसमें सभी डेटा के साथ छोड़ देना चाहिए क्योंकि इसमें' रिकॉर्डिंग 'फ़ोल्डर में एक फ़ाइल है जो मेरे लिए एक विशिष्ट निर्देशिका है।

मैंने कई पोस्ट देखे, लेकिन यह कई विशिष्ट फ़ाइल नामों से लिंक करता है। किसी भी मदद की बहुत सराहना की जाएगी क्योंकि मुझे एक सप्ताह में कई बार करने की आवश्यकता है।


क्या रिकॉर्डिंग हमेशा निर्देशिका में पहले स्तर पर है? भी: मुख्य निर्देशिका के अंदर पहले स्तर पर सभी फ़ोल्डर्स हैं?
जैकब व्लिजम

A शीर्ष स्तर की निर्देशिका है जिसमें इसमें क्रमांकित निर्देशिकाएं हैं। और गिने हुए निर्देशिकाओं में इसमें 'रिकॉर्डिंग' फ़ोल्डर और साथ ही कुछ 'txt' फाइलें शामिल हैं जैसे कि। और 'रिकॉर्डिंग' में इसमें फाइलें हो सकती हैं या नहीं भी ..
डेरेक जेम्स

क्या आप अपने पाठ की तस्वीर हटा देंगे और वास्तविक पाठ को अपने प्रश्न में रख देंगे। हमें संसाधित करने के लिए पाठ के चित्र बोझिल हैं। वास्तविक पाठ का उपयोग अन्य अंतर्निहित आवश्यकताओं के बीच काफी अधिक सुविधाजनक है।
एलडी जेम्स

मैंने वही किया जो आपने जेम्स से पूछा था ..
डेरेक जेम्स

जवाबों:


12

नीचे दी गई स्क्रिप्ट ठीक वैसा ही करेगी जैसा आप वर्णन करते हैं:

  1. एक निर्देशिका के अंदर फ़ोल्डरों को सूचीबद्ध करता है
  2. "रिकॉर्डिंग" नामक एक फ़ोल्डर के लिए प्रत्येक फ़ोल्डर के अंदर दिखता है

    • यदि यह मौजूद है और खाली है, तो यह अपने बेहतर फ़ोल्डर को हटा देता है
    • यदि यह मौजूद नहीं है, तो यह अपने बेहतर फ़ोल्डर को भी हटा देता है
    • ए के अंदर पहले स्तर की फाइलें हटाई नहीं जाएंगी।

एक छवि में:

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. इसे (पूर्ण!) निर्देशिका के साथ चलाएँ (कमांड में तर्क के रूप में, आपके उप-उदाहरणों, ए को अपने उदाहरण में शामिल करें):

    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. इसे (पूर्ण!) निर्देशिका के साथ चलाएं (आपके उपखंड, आपके उदाहरण में 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))

ध्यान दें

कृपया परीक्षण निर्देशिका पर पहले यह सुनिश्चित करने के लिए दौड़ें कि यह वही है जो आप चाहते हैं।


इस कोड ने वास्तव में मदद की और यह कहा गया काम किया। कोड के लिए धन्यवाद। वास्तव में सहायक है।
डेरेक जेम्स

मान लीजिए अगर मुझे दो फ़ोल्डर या अधिक रखने और जांचने की आवश्यकता है, तो मैं इस कोड में कैसे कर पाऊंगा? जोड़ने 'या' या पाइप '| 'कहीं .. सुमन को सुझाव देना!
डेरेक जेम्स

हाय @DerekJames जिसे केवल एक मामूली संपादन की आवश्यकता है, मैं आज दोपहर को पोस्ट करूंगा।
जैकब व्लिजम

@ डेरेक, प्रतीक्षा करें, यदि कोई फ़ोल्डर खाली है, या सभी को बेहतर फ़ोल्डर को हटा दिया जाना चाहिए ? वहाँ एक बेहतर dir में उनमें से कई हो सकता है?
जैकब व्लिजम

मान लीजिए @ जैकोब, मेरे पास दो फ़ोल्डर हैं 'रिकॉर्डिंग' और 'वीडियो'। इसे दोनों की जांच करनी चाहिए। यदि किसी भी सबफ़ोल्डर में फ़ाइल होती है तो फ़ोल्डर '635623' शड डिलीट नहीं किया जाएगा। और अगर यह किया जा सकता है, तो यह जांचने के लिए अधिक फ़ोल्डर्स जोड़ने की क्षमता भी है ...
डेरेक जेम्स

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 -type d -name 'रिकॉर्डिंग' -empty -printf '% h \ 0' खोजें | xargs -0 echo rm -rf यह केवल "rm -rf" प्रिंट कर रहा है और A -ype d -name 'रिकॉर्डिंग' -empty -printf '% h \ 0' खोजें | xargs -0 rm -rf काम नहीं कर रहा है ... क्या मैं कुछ गलत कर रहा हूँ ..
डेरेक जेम्स

@DerekJames को आपको वास्तविक निर्देशिका के साथ A को बदलना होगा।
याकूब व्लिजम

क्या रिकॉर्डिंग के नाम के स्थान पर नियमित रूप से अभिव्यक्ति देना ठीक रहेगा क्योंकि ओपी ने नंबरों के साथ फाइल के नाम दिए थे, कहते हैं [\d]*?
जॉर्ज उदेन ने

@JacobVlijm: मैंने वास्तविक निर्देशिका के साथ प्रतिस्थापित किया, लेकिन अभी भी नहीं?
डेरेक जेम्स

@DerekJames जो अजीब है! यह मेरे सिस्टम पर काम करता है, लेकिन आप पहले निर्देशिका में सीडी को भूल गए होंगे? प्रतीक्षावात, इससे कोई फर्क नहीं पड़ना चाहिए ...
याकूब व्लिजम

3

यहाँ एक सरल बैश समाधान है:

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

यह काम करता है क्योंकि rmdirनिर्देशिका खाली नहीं होने पर विफल हो जाएगा, और जब तक सफल नहीं होता तब तक निष्पादित होने से &&रोक देगा । ग्लोब सुनिश्चित करता है कि आप केवल निर्देशिकाओं पर काम कर रहे हैं, इसलिए अन्य फाइलें प्रभावित नहीं होंगी।rm -rrmdir*/


स्मार्ट सोच! +1
जैकब व्लिजम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.