यदि किसी निर्देशिका में फ़ाइलें हैं, तो शेल स्क्रिप्ट से जाँच करना


116

एक शेल स्क्रिप्ट से, मैं कैसे जांच करूं कि किसी निर्देशिका में फाइलें हैं?

ऐसा ही कुछ

if [ -e /some/dir/* ]; then echo "huzzah"; fi;

लेकिन जो काम करता है अगर निर्देशिका में एक या कई फाइलें होती हैं (ऊपर वाला केवल 0 या 1 फाइलों के साथ काम करता है)।


आपके उदाहरण के लिए यह अच्छा है कि आप ksh और zsh में क्या चाहते हैं
डेव वेब

2
@DaveWebb नहीं यह नहीं है। यदि ग्लोब एक शब्द से अधिक तक फैलता है, तो zsh परीक्षण 'परीक्षण: बहुत सारे तर्क' की रिपोर्ट करता है।
जेन्स

"हुज़ाह" का अर्थ है "निर्देशिका खाली नहीं है"।
फनल

यदि निर्देशिका में केवल एक खाली उपनिर्देशिका है, तो क्या वह "फाइल युक्त" के रूप में गिना जाता है?
कीथ थॉम्पसन

जवाबों:


72

अब तक के समाधान का उपयोग करें ls। यहां सभी बैश समाधान है:

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi

8
जब तक आप स्क्रिप्ट के अंत में विकल्पों को उनके मूल मूल्य पर वापस सेट करना याद रखते हैं :)
जीन

यह एक थोड़ा सुधरा हुआ संस्करण है जो बैश सेटिंग्स को रीसेट करने का ख्याल रखता है:shopt -q nullglob || resetnullglob=1; shopt -s nullglob; shopt -q dotglob || resetdotglob=1; shopt -s dotglob; files=(/some/dir/*); [ "$files" ] && echo "wowzers"; [ "$resetdotglob" ] && shopt -u dotglob; [ "$resetnullglob" ] && shopt -u nullglob;
user123444555621

12
सेटिंग्स को रीसेट करने के लिए एक files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*)
सबस्क्रिप्शन का

7
@teambob यदि एक सब-शेल का उपयोग कर रहा है: files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*) तो यदि स्टेटमेंट को बदलना चाहिए if [ ${#files} -gt 0 ];या हो सकता है कि आप सब-शेल कमांड के चारों ओर () भूल गए हों? files=($(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*))
stoutyhk

2
@stoutyhk $ (...) सेटिंग्स को पुनर्स्थापित करता है, कोई अलग उपधारा आवश्यक नहीं है। $ (...) का उपयोग करने से शेल का एक नया उदाहरण बन जाता है। कमांड समाप्त होने के बाद इस नए उदाहरण का वातावरण निकाल दिया जाता है। संपादित करें: एक संदर्भ मिला tldp.org/LDP/abs/html/commandsub.html "कमांड प्रतिस्थापन एक सबस्क्रिप्शन को आमंत्रित करता है।"
टीमब जूल 15'13

140

तीन बेहतरीन तरकीबें


shopt -s nullglob dotglob; f=your/dir/*; ((${#f}))

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

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

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

#Bash IRC चैनल के लिए 'आधिकारिक' FAQ पर एक समान विकल्प और अधिक विवरण (और अधिक उदाहरण) हैं :

if (shopt -s nullglob dotglob; f=(*); ((${#f[@]})))
then
  echo "contains files"
else 
  echo "empty (or does not exist, or is a file)"
fi

[ -n "$(ls -A your/dir)" ]

यह ट्रिक 2007 में पोस्ट किए गए nixCraft के लेख से प्रेरित है । 2>/dev/nullआउटपुट त्रुटि को दबाने के लिए जोड़ें "No such file or directory"
यह भी देखें एंड्रयू टेलर के जवाब (2008) और gr8can8dian के जवाब (2011)।

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

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

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

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


[ -n "$(find your/dir -prune -empty)" ]

यह पिछले चाल से प्रेरित है gravstar का जवाब जहां -maxdepth 0ने ले ली है -pruneऔर द्वारा सुधार किया फिल्स की टिप्पणी।

if [ -n "$(find your/dir -prune -empty 2>/dev/null)" ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

भिन्नता का उपयोग करते हुए -type d:

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

स्पष्टीकरण:

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

नोट: आप [ -n "$(find your/dir -prune -empty)" ]नीचे दिए गए छोटे संस्करण को भी बदल सकते हैं:

if [ `find your/dir -prune -empty 2>/dev/null` ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

यह अंतिम कोड अधिकांश मामलों में काम करता है लेकिन इस बात से अवगत रहें कि दुर्भावनापूर्ण पथ एक आदेश को व्यक्त कर सकते हैं ...


2
मुझे लगता [ -n "$(find "your/dir" -prune -empty)" ]है कि निर्देशिका पथ की पुनरावृत्ति से बचने के लिए आप खोज विकल्प को सरल बना सकते हैं ।
फिल्स

if [ ``ls -A your/dir`` ]एक स्क्रिप्ट का उपयोग करते समय मैं इस निष्कर्ष पर पहुंचा था कि यह 0, 1 या 2 उपनिर्देशिकाओं वाली निर्देशिका के लिए ठीक काम करता है, लेकिन 2 से अधिक उपनिर्देशिकाओं वाली निर्देशिका के लिए विफल रहता है। line 17: [: 20150424-002813: unary operator expectedजहां 20150424-002813निर्देशिका नामों में से एक था। प्रयुक्त शेल था /bin/bash/। मैंने अंत में इसे बदल दियाls "$destination" | tail -1
क्रिस्टोफ़ डे ट्रॉयर

हाय @ChristopheDeTroyer मैं आपके मुद्दे को पुन: पेश नहीं कर सकता। मेरी तरफ if [ ``ls -A my/dir`` ]से त्रुटि पर बाहर निकलता है bash: [: -A: binary operator expected। बैश संस्करण 4.1.2 और 4.2.53 पर परीक्षण किया गया।
ओलिब्रे

1
खैर, मुझे कथित असंगतता के कारण टिप्पणी करने के लिए मुख्य रूप से प्रेरित किया गया था (चूंकि -nसंस्करण शीर्ष रेखा में था, लेकिन फिर नीचे के पैराग्राफ में नहीं था)। तो, हाँ, यह ठीक है।
मैक्सक्लेपज़िग

1
मैं आपके एन समाधान का उपयोग कर रहा हूं, फिर भी मेरी स्क्रिप्ट स्टिल इस बारे में शिकायत करती है ls: cannot access '/path': No such file or directory। क्या कोई रास्ता है जिससे मैं इस संदेश को दबा सकूं? मैं वहां चुपचाप विफल होना चाहूंगा।
फ्रीडो

48

निम्नलिखित के बारे में कैसे:

if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

इस तरह से निर्देशिका की सामग्री की पूरी सूची बनाने की कोई आवश्यकता नहीं है। readदोनों उत्पादन त्यागने और केवल जब कुछ पढ़ा है सच का मूल्यांकन अभिव्यक्ति बनाने के लिए है (यानी /some/dir/द्वारा खाली पाया जाता है find)।


3
या बसfind /some/dir/ -maxdepth 0 -empty -exec echo "huzzah" \;
DoubleDown

5
+1 यह सबसे सुरुचिपूर्ण समाधान है। इसमें lsआउटपुट की पार्सिंग शामिल नहीं है और यह गैर-डिफ़ॉल्ट शेल विशेषताओं पर निर्भर नहीं करता है।

7
हालांकि, यह गैर-मानक -maxdepthऔर -emptyप्राइमरी पर निर्भर करता है ।
chepner

21

प्रयत्न:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi

यह मेरे लिए काम किया है, लेकिन मैं इस d * mn संदेश को प्रारूपित नहीं कर सकता हूँ !!! <br> निर्यात tmp = /bin/ls <some_dir>/* 2> /dev/nullयदि [! -z "$ tmp"]; तब इको समथिंग फाई
एंड्रयूस्टोन

1
मेरे जैसे बैश बेवकूफों के लिए, यदि आप इसके विपरीत की जाँच करना चाहते हैं - कि निर्देशिका खाली है - बस का उपयोग करें अगर [-z ls /some/dir/*]; फिर गूंज "हुजह"; फाई
क्रिस मोसिनची

4
आप -nइसके बजाय उपयोग कर सकते हैं ! -z(वे दोनों समतुल्य हैं, लेकिन जब मौजूद हैं तो छोटे रूप का उपयोग क्यों नहीं करते)।
n.st

WIth ZSH यह उदाहरण एक त्रुटि फेंकता है, विचार यह है कि त्रुटि को फेंकना नहीं है ... BigGray% if [ ! -z ls / some / dir / / @]; फिर गूंज "हुजह"; Fi zsh: कोई मैच नहीं मिला: / कुछ / dir / * `
Hvisage

मेरे लिए काम नहीं करता है बिना ls...
कोस

15
# Works on hidden files, directories and regular files
### isEmpty()
# This function takes one parameter:
# $1 is the directory to check
# Echoes "huzzah" if the directory has files
function isEmpty(){
  if [ "$(ls -A $1)" ]; then
    echo "huzzah"
  else 
    echo "has no files"
  fi
}

15

कई फाइलों के साथ निर्देशिकाओं का ध्यान रखें! lsकमांड का मूल्यांकन करने में कुछ समय लग सकता है ।

IMO सबसे अच्छा समाधान वह है जो उपयोग करता है

find /some/dir/ -maxdepth 0 -empty



4
# जाँचता है कि क्या किसी निर्देशिका में कोई गैर-प्रतिबंधित फ़ाइल है।
#
# उपयोग: अगर "$ HOME" खाली है; फिर गूंज "घर में स्वागत है"; फाई
#
खाली है() {
    $ 1 / * में _ief के लिए; करना
        अगर [-e "$ _ief"]; फिर
            वापसी 1
        फाई
    किया हुआ
    वापसी ०
}

कुछ कार्यान्वयन नोट:

  • forपाश एक बाहरी के लिए एक कॉल से बचा जाता है lsप्रक्रिया। यह अभी भी सभी निर्देशिका प्रविष्टियों को एक बार पढ़ता है। यह केवल एक सी प्रोग्राम लिखकर दूर किया जा सकता है जो स्पष्ट रूप से रीडिर () का उपयोग करता है।
  • test -eपाश अंदर एक खाली निर्देशिका, जिस स्थिति में चर के मामले पकड़ता _iefमूल्य "somedir / *" निर्दिष्ट किया जाएगा। केवल अगर वह फ़ाइल मौजूद है तो फ़ंक्शन "nonempty" वापस आ जाएगा
  • यह फ़ंक्शन सभी POSIX कार्यान्वयन में काम करेगा। लेकिन ध्यान रखें कि Solaris / bin / sh उस श्रेणी में नहीं आता है। इसका testकार्यान्वयन -eध्वज का समर्थन नहीं करता है ।

1
यदि dotglobयह सेट नहीं है तो यह निर्देशिका में dotfiles को अनदेखा करेगा -shopt -s dotglob
l0b0

4

यह मुझे बताता है कि क्या निर्देशिका खाली है या यदि यह नहीं है, तो इसमें कितनी फाइलें हैं।

directory="/some/dir"
number_of_files=$(ls -A $directory | wc -l)

if [ "$number_of_files" == "0" ]; then
    echo "directory $directory is empty"
else
    echo "directory $directory contains $number_of_files files"
fi

क्या कोई मुझे समझा सकता है कि मुझे क्यों अपमानित किया गया? यदि मैं क्रेप्स लिख रहा हूं, तो ईद writing क्यों जानना पसंद करते हैं;)
दाइश

1
मैंने इसे कम नहीं किया, लेकिन एक अनुमान के अनुसार यह इसलिए है क्योंकि आप इसका आउटपुट पार्सls कर रहे हैं ।
टोबी स्पाइट

जुड़ा हुआ लेख अस्पष्ट है? यदि हां, तो लेखक को ईमेल करें (मुझे नहीं)।
टॉबी स्पाइट

1
@TobySpeight मुझे बिंदु दिखाई देता है। लेकिन इस मामले में मैं उन पंक्तियों को गिन रहा हूं जो उन्हें नहीं मानती हैं। यह केवल तभी गलत परिणाम देना चाहिए जब किसी फ़ाइल नाम में एक नई पंक्ति हो। और यदि फ़ाइल के नाम में नई लाइनें हैं, तो कुछ अधिक महत्वपूर्ण होना चाहिए च ** कहीं भी?)
दाशी

3

यह वास्तव में देर से प्रतिक्रिया हो सकती है लेकिन यहां एक समाधान है जो काम करता है। यह लाइन केवल फाइलों की वें अस्तित्व को पहचानती है! अगर निर्देशिका मौजूद है तो यह आपको एक गलत सकारात्मक नहीं देगा।

if find /path/to/check/* -maxdepth 0 -type f | read
  then echo "Files Exist"
fi

2
dir_is_empty() {
   [ "${1##*/}" = "*" ]
}

if dir_is_empty /some/dir/* ; then
   echo "huzzah"
fi

मान लें कि नाम की एक फ़ाइल नहीं है *में /any/dir/you/check, उस पर काम करना चाहिए bash dash posh busybox shऔर zshलेकिन (zsh के लिए) की आवश्यकता होती है unsetopt nomatch

प्रदर्शन किसी भी lsउपयोग *(ग्लोब) के लिए तुलनीय होना चाहिए , मुझे लगता है कि कई नोड्स के साथ निर्देशिकाओं पर धीमी गति से होगा (मेरी /usr/bin3000+ फाइलें धीमी नहीं हुईं), सभी डायर / फ़ाइलनाम (और अधिक आवंटित करने के लिए कम से कम मेमोरी का उपयोग करेंगे) जैसा कि वे सभी तर्कों के रूप में कार्य करने के लिए (हल किए गए) हैं, कुछ शेल में संभवतः तर्कों की संख्या और / या तर्क की लंबाई की सीमा होती है।

एक पोर्टेबल फास्ट ओ (1) शून्य संसाधन तरीका यह जांचने के लिए कि क्या कोई निर्देशिका खाली है, अच्छा होगा।

अपडेट करें

संस्करण ऊपर छिपा फ़ाइलें / dirs के लिए खाते में नहीं है, मामले में कुछ और परीक्षण की आवश्यकता है, की तरह is_emptyसे अमीर के श (इसे POSIX शेल) चाल :

is_empty () (
cd "$1"
set -- .[!.]* ; test -f "$1" && return 1
set -- ..?* ; test -f "$1" && return 1
set -- * ; test -f "$1" && return 1
return 0 )

लेकिन, इसके बजाय, मैं कुछ इस तरह के बारे में सोच रहा हूं:

dir_is_empty() {
    [ "$(find "$1" -name "?*" | dd bs=$((${#1}+3)) count=1 2>/dev/null)" = "$1" ]
}

तर्क से फिसलने के अंतर के बारे में कुछ चिंताएं और डिर के खाली होने पर खोज के आउटपुट में अंतर, और अनुगामी newlines (लेकिन यह संभालना आसान होना चाहिए), दुख की बात है कि मेरे busybox shशो पर क्या है शायद find -> ddआउटपुट ट्रंक के साथ पाइप पर एक यादृच्छिक रूप से ( अगर मैंने catआउटपुट का उपयोग हमेशा एक जैसा किया है, ddतो तर्क के साथ लगता है count)।


मुझे पोर्टेबल समाधान पसंद है। मैं वही जवाब देने आया था। मैंने इसे अलग तरह से लिखा था (यदि निर्देशिका नहीं है तो 2 लौटाएं)। इसके अलावा, इन पोर्टेबल समाधानों में किसी भी बाहरी कार्यक्रमों को न कहने का लाभ है, जो कि विवश या एम्बेडेड सिस्टम के लिए प्लस के रूप में गिना जा सकता है। मुझे केवल यह चिंता है कि "()" का उपयोग करके एक नया उपप्रकार (या कम से कम बलों को पर्यावरण और सामान की प्रतिलिपि बनाने और फिर वापस स्विच करने के लिए बनाया जा सकता है)। इस पर एक नज़र डालें: is_empty () {_d = "$ {1: -।}"; [! -d "$ {_ d}"] && वापसी 2; सेट - "$ {_ d}" / * "$ {_ d}" /। ["$ { }" = "$ {_ d} / $ {_ d} /!]!] * $ {_ d} /..?*"]; };
डिएगो ऑगस्टो मोलिना

@DiegoAugustoMolina हाल ही में एक परियोजना में मुझे फिर से यह परीक्षण करना पड़ा था, अगर कोई निर्देशिका खाली थी, तो शुरुआत में मैंने अजगर का इस्तेमाल किया था, क्योंकि जब से मैंने व्यावहारिक रूप से बस इसके लिए अजगर स्थापित किया, मैंने सी में परीक्षण लागू किया, कार्यान्वयन चरम पर है भोज, मुझे आश्चर्य है कि इसे एक परीक्षण के रूप में या एक स्टैंड-अलोन कमांड के रूप में क्यों नहीं जोड़ा गया
एलेक्स

1
मैं भी एक (वास्तव में) विवश प्रणाली के लिए हाल ही में इस समस्या के समाधान की आवश्यकता है। मैंने किसी भी अतिरिक्त चर का उपयोग करने के लिए पिछले कोड को थोड़ा अनुकूलित किया। Hackish और बदसूरत दिखने वाला वन-लाइनर है लेकिन महान है। खुद की सेवा करें:is_empty(){ [ ! -d "${1}" ] && return 2;set -- "${1}" "${1}"/* "${1}"/.[!.]* "${1}"/..?*;[ "${*}" = "${1} ${1}/* ${1}/.[!.]* ${1}/..?*" ]; };
डिएगो ऑगस्टो मोलिना

2

ZSH

मुझे पता है कि सवाल बैश के लिए चिह्नित किया गया था; लेकिन, सिर्फ संदर्भ के लिए, zsh उपयोगकर्ताओं के लिए:

गैर-खाली निर्देशिका के लिए परीक्षण

यह जाँचने के लिए कि fooक्या गैर-रिक्त है:

$ for i in foo(NF) ; do ... ; done

जहां, यदि fooगैर-रिक्त है, तो forब्लॉक में कोड निष्पादित किया जाएगा।

खाली निर्देशिका के लिए परीक्षण करें

यह जाँचने के लिए कि fooक्या खाली है:

$ for i in foo(N/^F) ; do ... ; done

जहां, यदि fooखाली है, तो forब्लॉक में कोड निष्पादित किया जाएगा।

टिप्पणियाँ

हमें fooऊपर दी गई निर्देशिका को उद्धृत करने की आवश्यकता नहीं थी , लेकिन हम ऐसा कर सकते हैं:

$ for i in 'some directory!'(NF) ; do ... ; done

हम एक से अधिक ऑब्जेक्ट का परीक्षण भी कर सकते हैं, भले ही वह निर्देशिका न हो:

$ mkdir X     # empty directory
$ touch f     # regular file
$ for i in X(N/^F) f(N/^F) ; do echo $i ; done  # echo empty directories
X

जो कुछ भी एक निर्देशिका नहीं है उसे सिर्फ अनदेखा किया जाएगा।

अतिरिक्त

चूंकि हम ग्लोबिंग कर रहे हैं, हम किसी भी ग्लोब (या ब्रेस विस्तार) का उपयोग कर सकते हैं:

$ mkdir X X1 X2 Y Y1 Y2 Z
$ touch Xf                    # create regular file
$ touch X1/f                  # directory X1 is not empty
$ touch Y1/.f                 # directory Y1 is not empty
$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ for i in {X,Y}*(N/^F); do printf "$i "; done; echo  # print empty directories
X X2 Y Y2

हम उन वस्तुओं की भी जांच कर सकते हैं जिन्हें एक सरणी में रखा गया है। उदाहरण के लिए ऊपर दी गई निर्देशिकाओं के साथ:

$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ arr=(*)                     # place objects into array "arr"
$ for i in ${^arr}(N/^F); do printf "$i "; done; echo
X X2 Y Y2 Z

इस प्रकार, हम उन वस्तुओं का परीक्षण कर सकते हैं जो पहले से ही एक सरणी पैरामीटर में सेट हो सकते हैं।

ध्यान दें कि forब्लॉक में कोड , जाहिर है, बदले में प्रत्येक निर्देशिका पर निष्पादित होता है। यदि यह वांछनीय नहीं है, तो आप बस एक सरणी पैरामीटर को आबाद कर सकते हैं और फिर उस पैरामीटर पर काम कर सकते हैं:

$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories

व्याख्या

Zsh उपयोगकर्ताओं के लिए (F)ग्लोब क्वालिफायर (देखें man zshexpn) है, जो "पूर्ण" (गैर-रिक्त) निर्देशिकाओं से मेल खाता है:

$ mkdir X Y
$ touch Y/.f        # Y is now not empty
$ touch f           # create a regular file
$ ls -dF *          # list everything in the current directory
f X/ Y/
$ ls -dF *(F)       # will list only "full" directories
Y/

क्वालीफायर (F)उन वस्तुओं को सूचीबद्ध करता है जो मेल खाते हैं: एक निर्देशिका है और खाली नहीं है। तो, (^F)मेल खाता है: निर्देशिका नहीं या खाली है। इस प्रकार, (^F)अकेले भी नियमित फ़ाइलों को सूचीबद्ध करेगा, उदाहरण के लिए। इस प्रकार, जैसा कि zshexpमैन पेज पर समझाया गया है , हमें (/)ग्लोब क्वालिफायर की भी आवश्यकता है , जो केवल निर्देशिकाओं को सूचीबद्ध करता है:

$ mkdir X Y Z
$ touch X/f Y/.f    # directories X and Y now not empty
$ for i in *(/^F) ; do echo $i ; done
Z

इस प्रकार, यह जांचने के लिए कि क्या दी गई निर्देशिका खाली है, इसलिए आप चला सकते हैं:

$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished

और सिर्फ यह सुनिश्चित करने के लिए कि एक गैर-खाली निर्देशिका कैप्चर नहीं की जाएगी:

$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished

ऊप्स! चूंकि Yखाली नहीं है, zsh को (/^F)("निर्देशिका जो खाली हैं") के लिए कोई मेल नहीं मिलता है और इस प्रकार एक त्रुटि संदेश देता है जिसमें कहा गया है कि ग्लोब के लिए कोई मैच नहीं मिला। इसलिए हमें (N)ग्लोब क्वालिफायर के साथ इन संभावित त्रुटि संदेशों को दबाने की आवश्यकता है :

$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished

इस प्रकार, खाली निर्देशिकाओं के लिए हमें क्वालीफायर की आवश्यकता होती है (N/^F), जिसे आप निम्नानुसार पढ़ सकते हैं: "मुझे विफलताओं के बारे में चेतावनी न दें, निर्देशिकाएं पूर्ण नहीं हैं"।

इसी तरह, गैर-खाली निर्देशिकाओं के लिए हमें क्वालीफायर की आवश्यकता होती है (NF), जिसे हम इसी तरह पढ़ सकते हैं: "मुझे असफलताओं के बारे में चेतावनी न दें, पूर्ण निर्देशिकाएं"।


1

मुझे आश्चर्य है कि खाली निर्देशिकाओं पर ऊनी गाइड का उल्लेख नहीं किया गया है। यह गाइड, और वास्तव में ऊन के सभी प्रकार, शेल प्रकार के प्रश्नों के लिए पढ़ना चाहिए।

उस पृष्ठ से ध्यान दें:

कभी भी ls आउटपुट को पार्स करने की कोशिश न करें। यहां तक ​​कि ls- समाधान टूट सकता है (उदाहरण के लिए HP-UX पर, यदि आप रूट हैं, तो ls-A क्या करता है इसके ठीक विपरीत है यदि आप रूट नहीं हैं - और नहीं, मैं अविश्वसनीय रूप से कुछ नहीं बना सकता हूं बेवकूफ)।

वास्तव में, कोई भी प्रत्यक्ष प्रश्न से पूरी तरह बचना चाह सकता है। आमतौर पर लोग यह जानना चाहते हैं कि क्या कोई निर्देशिका खाली है क्योंकि वे फ़ाइलों को शामिल करने के लिए कुछ करना चाहते हैं, आदि बड़े प्रश्न को देखें। उदाहरण के लिए, इन खोज-आधारित उदाहरणों में से एक उपयुक्त समाधान हो सकता है:

   # Bourne
   find "$somedir" -type f -exec echo Found unexpected file {} \;
   find "$somedir" -maxdepth 0 -empty -exec echo {} is empty. \;  # GNU/BSD
   find "$somedir" -type d -empty -exec cp /my/configfile {} \;   # GNU/BSD

सबसे आम तौर पर, जो वास्तव में जरूरी है वह कुछ इस तरह है:

   # Bourne
   for f in ./*.mpg; do
        test -f "$f" || continue
        mympgviewer "$f"
    done

दूसरे शब्दों में, प्रश्न पूछने वाले व्यक्ति ने सोचा हो सकता है कि mympviewer जैसे त्रुटि संदेश से बचने के लिए एक स्पष्ट खाली-निर्देशिका परीक्षण की आवश्यकता थी: ./*.mpg: ऐसी कोई फ़ाइल या निर्देशिका नहीं जब वास्तव में इस तरह के परीक्षण की आवश्यकता न हो।



1

ओलिब्रे के जवाब से संकेत (या कई) लेना, मुझे बैश फ़ंक्शन पसंद है:

function isEmptyDir {
  [ -d $1 -a -n "$( find $1 -prune -empty 2>/dev/null )" ]
}

क्योंकि जब यह एक उप-संस्करण बनाता है, तो यह O (1) समाधान के करीब है जैसा कि मैं कल्पना कर सकता हूं और इसे एक नाम देने से यह पठनीय हो जाता है। मैं तब लिख सकता हूं

if isEmptyDir somedir
then
  echo somedir is an empty directory
else
  echo somedir does not exist, is not a dir, is unreadable, or is  not empty
fi

O (1) के रूप में, वहाँ एक से अधिक मामले हैं: यदि एक बड़ी निर्देशिका में सभी या सभी, लेकिन अंतिम प्रविष्टि हटा दी गई है, तो "खोजने" को यह निर्धारित करने के लिए पूरी बात पढ़नी पड़ सकती है कि क्या यह खाली है। मेरा मानना ​​है कि अपेक्षित प्रदर्शन ओ (1) है, लेकिन सबसे खराब स्थिति निर्देशिका आकार में रैखिक है। मैंने यह नहीं मापा है।


0

अब तक मैंने ऐसा जवाब नहीं देखा है जो grep का उपयोग करता है जो मुझे लगता है कि एक सरल उत्तर देगा (बहुत अधिक अजीब प्रतीकों के साथ नहीं)। यहां बताया गया है कि बोर्न शेल का उपयोग करके निर्देशिका में कोई भी फाइल मौजूद होने पर मैं कैसे जांच करूंगा:

यह निर्देशिका में फ़ाइलों की संख्या लौटाता है:

ls -l <directory> | egrep -c "^-"

जहाँ निर्देशिका लिखी है आप निर्देशिका पथ को भर सकते हैं। पाइप की पहली छमाही सुनिश्चित करती है कि आउटपुट का पहला चरित्र प्रत्येक फ़ाइल के लिए "-" है। egrep तब उस रेखा की संख्या को गिनता है जो नियमित रूप से अभिव्यक्ति का उपयोग करके उस प्रतीक से शुरू होती है। अब आपको बस इतना करना है कि आपके द्वारा प्राप्त की गई संख्या को स्टोर करें और इसकी तुलना करें जैसे कि बैकक्वाट्स का उपयोग करके:

 #!/bin/sh 
 fileNum=`ls -l <directory> | egrep -c "^-"`  
 if [ $fileNum == x ] 
 then  
 #do what you want to do
 fi

x आपकी पसंद का एक चर है।


0

प्रून चीजों और आखिरी जवाबों को मिलाकर, मैं समझ गया

find "$some_dir" -prune -empty -type d | read && echo empty || echo "not empty"

कि रिक्त स्थान के साथ पथ के लिए भी काम करता है



0

मैं इसके लिए जाऊंगा find:

if [ -z "$(find $dir -maxdepth 1 -type f)" ]; then
    echo "$dir has NO files"
else
    echo "$dir has files"

यह उपनिर्देशिकाओं के माध्यम से जाने के बिना, निर्देशिका में सिर्फ फाइलों की तलाश के आउटपुट की जांच करता है। तब यह इससे लिए गए -zविकल्प का उपयोग करके आउटपुट की जाँच करता है man test:

   -z STRING
          the length of STRING is zero

कुछ परिणाम देखें:

$ mkdir aaa
$ dir="aaa"

खाली डायर:

$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

बस इसमें dirs:

$ mkdir aaa/bbb
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

निर्देशिका में एक फ़ाइल:

$ touch aaa/myfile
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
$ rm aaa/myfile 

उपनिर्देशिका में एक फ़ाइल:

$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

0

कुछ वर्कअराउंड के साथ मुझे यह पता लगाने का एक सरल तरीका मिल सकता है कि क्या निर्देशिका में फाइलें हैं। यह विशेष रूप से .xml या .txt फ़ाइलों आदि की जाँच करने के लिए grep कमांड के साथ और अधिक विस्तार कर सकता है। Ex:ls /some/dir | grep xml | wc -l | grep -w "0"

#!/bin/bash
if ([ $(ls /some/dir | wc -l  | grep -w "0") ])
    then
        echo 'No files'
    else
        echo 'Found files'
fi

-1
if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;

मुझे यह पसंद है क्योंकि कमांड को क्रॉप करने वाले कोई उद्धरण या कोष्ठक नहीं हैं।
डेव वेब

यदि आप सेट करते हैं तो इसका उपयोग न करने के लिए सावधान रहें nullglob, क्योंकि तब lsकमांड सफल होगा।
स्टीव केहलेट

निर्देशिका में डॉट फाइलें होने की स्थिति में सभी वातावरण में काम नहीं होगा।
डिएगो ऑगस्टो मोलिना

-1

एक विशिष्ट लक्ष्य निर्देशिका का परीक्षण करने के लिए

if [ -d $target_dir ]; then
    ls_contents=$(ls -1 $target_dir | xargs); 
    if [ ! -z "$ls_contents" -a "$ls_contents" != "" ]; then
        echo "is not empty";
    else
        echo "is empty";
    fi;
else
    echo "directory does not exist";
fi;

-1

कमांड खोजने के साथ प्रयास करें। निर्देशिका को हार्डकोड या तर्क के रूप में निर्दिष्ट करें। फिर निर्देशिका के अंदर सभी फ़ाइलों को खोजने के लिए आरंभ करें। जाँच करें कि क्या रिटर्न की वापसी शून्य है। खोज के डेटा को प्रतिध्वनित करें

#!/bin/bash

_DIR="/home/user/test/"
#_DIR=$1
_FIND=$(find $_DIR -type f )
if [ -n "$_FIND" ]
then
   echo -e "$_DIR contains files or subdirs with files \n\n "
   echo "$_FIND"
else
echo "empty (or does not exist)"
fi

यदि निर्देशिका में खाली निर्देशिका या गैर-नियमित फ़ाइलें (सॉकेट्स, चार डिवाइसेस, सिमिलिंक आदि) हैं, तो यह काम नहीं करेगा। निर्देशिका खाली होने की सूचना दी जाएगी।
डिएगो ऑगस्टो मोलिना

@DiegoAugustoMolina अगर मुझे सही ढंग से समझ में आया था कि हम जाँच करना चाह रहे हैं कि क्या फाइलें मौजूद हैं (क्योंकि शाब्दिक रूप से फाइलें) -s तर्क का उपयोग किया गया था। लेकिन आपकी टिप्पणी अभी भी सच है।
.गियानक

-2

मैं ls - Aपोस्ट किए गए समाधानों को नापसंद करता हूं । सबसे अधिक संभावना है कि आप परीक्षण करना चाहते हैं यदि निर्देशिका खाली है क्योंकि आप इसे हटाना नहीं चाहते हैं। निम्नलिखित वह करता है। यदि आप अभी एक खाली फ़ाइल को लॉग इन करना चाहते हैं, तो निश्चित रूप से इसे हटाना और पुनः प्राप्त करना तेज है तो संभवतः अनंत फाइलों को सूचीबद्ध करना है?

यह काम करना चाहिए ...

if !  rmdir ${target}
then
    echo "not empty"
else
    echo "empty"
    mkdir ${target}
fi

4
यह काम नहीं करता है यदि उपयोगकर्ता के पास लिखने की अनुमति नहीं है ${target}/..
जेन्स

परीक्षण को विनाशकारी बनाने के लिए सिर्फ एक बुरा विचार। अन्य बातों के अलावा, यह दौड़ की स्थितियों का परिचय देता है।
4dummies

-2

मेरे लिए यह अच्छी तरह से काम करता है (जब डायर मौजूद है):

some_dir="/some/dir with whitespace & other characters/"
if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

पूरी जाँच के साथ:

if [ -d "$some_dir" ]; then
  if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; else "Dir is NOT empty" fi
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.