खाली निर्देशिका ढूँढना UNIX


90

मुझे निर्देशिकाओं की दी गई सूची के लिए खाली निर्देशिकाओं को खोजने की आवश्यकता है। कुछ निर्देशिकाओं के अंदर निर्देशिका है।

अगर अंदर निर्देशिकाएं खाली हैं, तो मैं कह सकता हूं कि मुख्य निर्देशिका खाली है अन्यथा यह खाली नहीं है।

मैं इसका परीक्षण कैसे कर सकता हूं?

उदाहरण के लिए:

A>A1(file1),A2 this is not empty beacuse of file1
B>B1(no file) this is empty
C>C1,C2 this is empty

2
मुझे लगता है कि यहां मार्टिन का जवाब सबसे उपयुक्त है। वर्तमान स्वीकृत उत्तर केवल एक अपूर्ण छद्मकोश है।
लेओ लेपोल्ड हर्ट्ज़ o

जवाबों:


34

जांचें कि क्या find <dir> -type fकुछ भी आउटपुट करता है। यहाँ एक उदाहरण है:

for dir in A B C; do
    [ -z "`find $dir -type f`" ] && echo "$dir is empty"
done

2
नहीं, यह उपनिर्देशिका का उत्पादन नहीं करेगा। जो है उसके लिए -type fहै।
मार्सेलो कैंटोस

यदि कोई खाली फाइलें हैं , तो आपके समाधान से संदेश नहीं मिलेगा।
यासिर अरसानुकेव

3
यासिर: मुझे लगता है कि एक निर्देशिका जिसमें एक खाली फ़ाइल का घाव है, वह खाली नहीं है। क्या यह सही परिणाम नहीं होगा?
उक्को

2
@akostadinov: अगर मैं ओपी द्वारा बताई गई निर्देशिकाओं और फाइलों को बनाता हूं mkdir A B C A/A1 A/A2 B/B1 C/C1 C/C2; touch A/A1/file1- और अपने उत्तर में कोड चलाता हूं, तो यह रिपोर्ट करता है कि ओपी द्वारा आवश्यक के रूप में बी और सी खाली हैं। तो आपको "यह काम नहीं करेगा" की तुलना में थोड़ा अधिक विशिष्ट होने की आवश्यकता होगी।
मार्सेलो कैंटोस

1
यदि आप मेरे जैसे बैश नोब हैं, तो देखें कि यहाँ क्या -z का मतलब है
ओमरऑथमैन

255

यह खाली निर्देशिकाओं के साथ आप क्या करना चाहते हैं, इस पर थोड़ा निर्भर करता है। जब मैं एक पेड़ के भीतर सभी खाली निर्देशिकाओं को हटाने की इच्छा रखता हूं, तो मैं testनिर्देशिका का उपयोग करता हूं ।

find test -depth -empty -delete

ऊपर दिए गए कमांड के बारे में ध्यान देने वाली एक बात यह है कि यह खाली फाइलों को भी हटा देगा , इसलिए इससे बचने के लिए -type d विकल्प का उपयोग करें ।

find test -depth -type d -empty -delete

-deleteफ़ाइलों और निर्देशिकाओं को देखने के लिए ड्रॉप करें।

यदि खाली निर्देशिका ट्री की आपकी परिभाषा यह है कि इसमें कोई फाइल नहीं है, तो आप कुछ find test -type fभी रिटर्न के आधार पर एक साथ कुछ चिपका सकते हैं।

find एक महान उपयोगिता है, और आरटीएफएम जल्दी और अक्सर यह समझने के लिए कि यह कितना कर सकता है :-)


8
-Dill तात्पर्य -depth (कम से कम GNU खोज के लिए 4.4.2)
डॉ। व्यक्ति व्यक्ति II

4
के बारे में पता नहीं था -empty, इतना सुविधाजनक!
रफ़ी

2
हालांकि मशीन पर जो नवीनतम और सबसे बड़ी लाइनक्स नहीं हैं। (ईजी सोलारिस), तो आपके पास कोई फैंसी खोज जैसी सुविधाएँ नहीं हैं -empty या -delete।
एंथनी

3
MacOS-X पर, लगभग खाली निर्देशिकाओं के लिए, find test -name ".DS_Store" -deleteपहले चलाएँ , फिर -empty deleteकमांड। यह भी ध्यान दें, pushdमूल निर्देशिका की तरह, ताकि यह find testबन जाए find ., लेकिन बाकी कमांड समान हैं।
ओली

1
@Martin क्या आप कृपया -depthयहाँ की परिभाषा जोड़ सकते हैं अर्थात क्योंकि गहराई-प्रथम ट्रैवर्सल प्रदर्शन करने के लिए खोज करते हैं, अर्थात, निर्देशिकाओं को पोस्ट-ऑर्डर में देखा जाता है और एक निर्देशिका में सभी प्रविष्टियाँ निर्देशिका से पहले ही काम करेगी। मुझे लगता है कि यह यहां प्रासंगिक है।
लेओ लेपोल्ड हर्ट्ज़ '

48

आप निम्न आदेश का उपयोग कर सकते हैं:

find . -type d -empty

1
-केवल खाली काम करता है यदि वर्तमान निर्देशिका पूरी तरह से खाली है, तो नहीं अगर सबट्री में कोई फाइल नहीं है।
मार्सेलो कैंटोस

@soField परीक्षण खोजा गया। FreeBSD और CentOS के साथ -type d -empty ठीक काम करता है। क्या आपका ओएस?
मच्छर

1
hp-ux इसलिए कोई खाली पैरामीटर नहीं है
soField

@soField तो, आप देखते हैं, यह बेहतर है (हम सभी के लिए) इस डेटा को अपने प्रश्न के शीर्ष पर पोस्ट करने के लिए ...
मग

2
खोज सोलारिस पर या तो खाली नहीं है, लेकिन इसमें गहराई-पहला ट्रैवर्सल लागू करने के लिए -depth है ताकि खाली उपनिर्देशिका को खाली किया जा सके, इससे पहले कि खालीपन के लिए मूल निर्देशिका की जाँच की जाए।
इरिक्मा

26
find directory -mindepth 1 -type d -empty -delete

यह वह संस्करण है जो मुझे सबसे दिलचस्प लगा। यदि अंदर निर्देशिका से निष्पादित किया जाता है , तो यह नीचे की सभी खाली निर्देशिकाओं को हटा देगा (यदि कोई निर्देशिका खाली मानी जाती है, यदि उसमें केवल खाली निर्देशिकाएँ हों)।

खाली होने पर माइंडप्थ ऑप्शन डायरेक्ट्री को डिलीट होने से रोकता है।


2
साथ rmdir --ignore-fail-on-non-empty -p directoryही माता-पिता से छुटकारा पाने के लिए आप इसका अनुसरण कर सकते हैं ।
पीट पीटरसन

@ पेइट पीटरसन मेरा आदेश उन निर्देशिकाओं को हटाने के लिए लगता है जिनमें केवल अन्य खाली निर्देशिकाएं होती हैं (जो कि ओपी भी चाहता है)। मैं ध्यान देता हूं कि आपका कमांड आमतौर पर एक निर्देशिका में उपयोगकर्ता को एक लापता आई-नोड के साथ छोड़ देगा, भले ही वे जो चाहें उसे पूरा करें, जो उनके लिए भ्रमित हो सकता है। शायद मुझे बात याद आ रही है।
डॉ। पर्सन II II

23

find . -type d -empty

वर्तमान ट्री में खाली निर्देशिकाओं और उप-निर्देशिकाओं को ढूँढता है और उनकी सूची बनाता है। उदाहरण के लिए खाली dirs और उपखंडों की सूची:

./2047
./2032
./2049
./2063
./NRCP26LUCcct1/2039
./NRCP26LUCcct1/2054
./NRCP26LUCcct1/2075
./NRCP26LUCcct1/2070

निर्देशिकाओं पर कोई कार्रवाई नहीं की जाती है। वे बस सूचीबद्ध हैं। यह मेरे लिए काम करता है।


16

बस खाली dirs पाते हैं

खाली निर्देशिकाओं को खोजने के लिए (जैसा कि प्रश्न शीर्षक में निर्दिष्ट किया गया है), मस्जिद का उत्तर सही है:

find -type d -empty

लेकिन -emptyबहुत पुराने findसंस्करणों पर उपलब्ध नहीं हो सकता है ( उदाहरण के लिए यह एचपी-यूएक्स का मामला है )। यदि यह आपका मामला है, तो नीचे खंड में वर्णित तकनीकों को देखें क्या कोई निर्देशिका खाली है?

खाली डायरियां हटाएं

यह थोड़ा मुश्किल है: मान लीजिए कि किसी निर्देशिका MyDirमें खाली निर्देशिकाएँ हैं। इन खाली निर्देशिकाओं को हटाने के बाद, MyDirएक खाली निर्देशिका बन जाएगी और इसे भी हटा दिया जाना चाहिए। इसलिए मैं rmdirविकल्प --parents(या -p) के साथ कमांड का उपयोग करता हूं जो संभव होने पर मूल निर्देशिकाओं को भी हटा देता है:

find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} +

पुराने findसंस्करण पर बयान +अभी तक समर्थित नहीं है, इसलिए आप ;इसके बजाय उपयोग कर सकते हैं :

find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} `;`

क्या कोई निर्देशिका खाली है?

इनमें से अधिकांश उत्तर बताते हैं कि अगर निर्देशिका खाली है तो कैसे जांच करें। इसलिए मैं यहां उन तीन अलग-अलग तकनीकों को प्रदान करता हूं जिन्हें मैं जानता हूं:

  1. [ $(find your/dir -prune -empty) = your/dir ]

    d=your/dir
    if [ x$(find "$d" -prune -empty) = x"$d" ]
    then
      echo "empty (directory or file)"
    else
      echo "contains files (or does not exist)"
    fi

    एक भिन्नता:

    d=your/dir
    if [ x$(find "$d" -prune -empty -type d) = x"$d" ]
    then
      echo "empty directory"
    else
      echo "contains files (or does not exist or is not a directory)"
    fi

    स्पष्टीकरण:

    • find -prunefind -maxdepth 0कम वर्णों का उपयोग करने के समान है
    • find -type d केवल निर्देशिका प्रिंट करता है
    • find -empty खाली निर्देशिका और फ़ाइलों को प्रिंट करता है

      > mkdir -v empty1 empty2 not_empty
      mkdir: created directory 'empty1'
      mkdir: created directory 'empty2'
      mkdir: created directory 'not_empty'
      > touch not_empty/file
      > find empty1 empty2 not_empty -prune -empty
      empty1
      empty2
  2. (( ${#files} ))

    यह ट्रिक 100% है bashलेकिन एक उप-शेल को इनवोक (स्पॉ) करता है। विचार ब्रूनो डी फेन का है और टीमबोब द्वारा सुधार किया गया है की टिप्पणी से । यदि आप उपयोग करते हैं तो मैं इसे सलाह देता हूं और अगर आपकी स्क्रिप्ट पोर्टेबल नहीं है।

    files=$(shopt -s nullglob dotglob; echo your/dir/*)
    if (( ${#files} ))
    then 
      echo "contains files"
    else 
      echo "empty (or does not exist or is a file)"
    fi

    नोट: एक खाली निर्देशिका और एक गैर-मौजूदा वाले के बीच कोई अंतर नहीं है (और यहां तक ​​कि जब भी पथ एक फ़ाइल है)।

  3. [ $(ls -A your/dir) ]

    यह ट्रिक 2007 में पोस्ट किए गए nixCraft के लेख से प्रेरित है। एंड्रयू टेलर ने 2008 में और gr8can8dian ने 2011 में जवाब दिया ।

    if [ "$(ls -A your/dir)" ]
    then
      echo "contains files"
    else
      echo "empty (or does not exist or is a file)"
    fi

    या एक-पंक्ति बैशिज़्म संस्करण:

    [[ "$(ls -A your/dir)" ]] && echo "contains files" || echo "empty or ..."

    नोट: जब निर्देशिका मौजूद नहीं है, तो lsरिटर्न $?=2। लेकिन एक फ़ाइल और एक खाली निर्देशिका के बीच कोई अंतर नहीं है।


rmdir -vpजब से मुझे बस एक रूट के तहत सभी खाली डायरियों को हटाने की जरूरत नहीं है, लेकिन एक फ़ाइल को हटाने के बाद खाली डायर और माता-पिता डायरियों की जांच करने की आवश्यकता है, इससे मुझे बहुत मदद मिली। मेरी स्थिति में जब तक वे पेड़ में नहीं होते हैं तब तक खाली डायरियां ठीक होती हैं। धन्यवाद!
एथन होहेंस

2

इस पुनरावर्ती कार्य को करने के लिए लगता है:

# Bash
findempty() {
    find ${1:-.} -mindepth 1 -maxdepth 1 -type d | while read -r dir
    do
        if [[ -z "$(find "$dir" -mindepth 1 -type f)" ]] >/dev/null
        then
            findempty "$dir"
            echo "$dir"
        fi
    done
}

इस उदाहरण निर्देशिका संरचना को देखते हुए:

    ।
    | - dir1 /
    | - dir2 /
    | `- डीआईआरबी /
    | - dir3 /
    | `- डीआईआरसी /
    | `- फाइल 5
    | - dir4 /
    | | - dirD /
    | `- फाइल 4
    `- dir5 /
        `- dirE /
            `- dir_V /

उस फ़ंक्शन को चलाने का परिणाम होगा:

    ./dir1
    ./dir5/dirE/dir_V
    ./dir5/dirE
    ./dir5
    ./dir2/dirB
    ./dir2

जो याद आती है /dir4/dirD। यदि आप पुनरावर्ती कॉल findempty "$dir"को स्थानांतरित करते हैं fi, तो फ़ंक्शन उस निर्देशिका को उसके परिणामों में शामिल करेगा।


2

कैसे के बारे में rmdir *? वह आदेश गैर-रिक्त निर्देशिकाओं पर विफल हो जाएगा।


सामान्य सफाई के लिए मैंने कभी-कभी कुछ किया है। rmdir */*/* */* * हालांकि ऐसी चीजें भी की जाती हैं जो 'डॉट-फाइल्स' को हैंडल नहीं करती हैं, लेकिन तब मैनुअल स्थितियों में (डेटा फ़ाइलों की सफाई) आप आमतौर पर 'डॉट-फाइल्स' की उम्मीद नहीं करते हैं। पुनरावर्ती तरीके, हालांकि अधिक स्वचालित सामान्य सफाई के लिए हैं, विशेष रूप से बहुत बड़ी निर्देशिका संरचनाओं में।
एंथनी

एक मामले में और अधिक जटिल था क्योंकि मुझे खाली निर्देशिकाओं को हटाने की जरूरत थी, जहां 'खाली' में ऐसी निर्देशिकाएं शामिल थीं जिनमें एक 'रीडमी' फाइल हो सकती है। निर्देशिका में कुछ भी और यह 'खाली' नहीं था। उस उदाहरण में निर्देशिका संरचना में हजारों उप-निर्देशिकाएं शामिल थीं।
एंथनी

1

यदि कोई निर्देशिका खाली है (या मौजूद नहीं है) और तो अन्यथा निम्न कमांड 1 देता है (इसलिए !शेल स्क्रिप्ट में रिटर्न कोड को पलटना संभव है ):

find $dir -type d -prune -empty -exec false {} +

0

मैंने एक सरल संरचना इस प्रकार बनाई:

test/
test/test2/
test/test2/test2.2/
test/test3/
test/test3/file

test/test3/fileकुछ जंक पाठ शामिल है।

केवल खाली निर्देशिका के रूप में find test -emptyरिटर्न जारी करना test/test2/test2.2


सेशन टेस्ट / टेस्ट 2 को भी वापस करने के लिए कहता है

वास्तव में। लेकिन मुझे लगा कि वह आगे जाने के लिए खोज मैन पेज पढ़ सकता है। एक स्क्रिप्ट जो परिणामों के आधार पर गहराई को समायोजित करती है वह ठीक काम करेगी।
जेम्स सुमेर

यह mye उपयोग के लिए सबसे उपयोगी संस्करण था, धन्यवाद
Andreas

0

एक सरल दृष्टिकोण होगा,

$ [ "$(ls -A /path/to/direcory)" ] && echo "not empty" || echo "its empty"

भी,

if [ "$(ls -A /path/to/direcory)" ]; then
   echo "its not empty"
else 
   echo "empty directory"

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