उन सभी निर्देशिकाओं को सूचीबद्ध करें जिनके पास किसी फ़ाइल नाम के साथ फ़ाइल नहीं है


12

मैं उन सभी निर्देशिकाओं को सूचीबद्ध करने में कैसे जाऊंगा जिनके पास एक फ़ाइल नाम के साथ फ़ाइल नहीं है? जैसे इस पेड़ को दिया

/
  /a
     README
     file001
     file002
  /b
     README
     file001
  /c
     file003

मैं उन निर्देशिकाओं को सूचीबद्ध करना चाहता हूं जिनके पास नाम की कोई फ़ाइल नहीं है README, इस मामले में यह निर्देशिका होगी /c। मुझे यह कैसे करना है? मैं किसी भी वाक्यविन्यास का उपयोग कर के बारे में सोच भी नहीं सकते find


शर्म की बात है ओह शर्म की बात है आप भी खोज नहीं किया: askubuntu.com/questions/196960/...
SLM

खोज करते समय मैंने सही कीवर्ड के बारे में नहीं सोचा था।
Renan

2
मैं बस चॉप कर रहा हूं। मैं कई बार वहाँ गया हूँ जहाँ मैं कुछ खोजने के लिए सही शब्द के बारे में सोच नहीं सकता था 8-)।
slm

जवाबों:


5

findGNU जैसा क्रियान्वयन मान लेना जो एक तर्क में एम्बेडेड को findस्वीकार करता {}है -exec:

$ find . -type d \! -exec test -e '{}/README' \; -print

उदाहरण

यहाँ 5/5 के माध्यम से 1/1 निर्देशिकाओं में एक README है, अन्य डायर खाली हैं।

$ tree 
.
|-- 1
|   `-- 1
|       `-- README
|-- 10
|   `-- 10
|-- 2
|   `-- 2
|       `-- README
|-- 3
|   `-- 3
|       `-- README
|-- 4
|   `-- 4
|       `-- README
|-- 5
|   `-- 5
|       `-- README
|-- 6
|   `-- 6
|-- 7
|   `-- 7
|-- 8
|   `-- 8
`-- 9
    `-- 9

अब जब हम अपने findकमांड के इस संस्करण को चलाते हैं :

$ find . -type d \! -exec test -e '{}/README' \; -print
.
./10
./10/10
./7
./7/7
./9
./9/9
./6
./6/6
./5
./8
./8/8
./4
./1
./3
./2

संदर्भ


उप निर्देशिकाओं की खोज करने के लिए कमांड को कैसे संशोधित करें, जिनके पास एक विशिष्ट फ़ाइल एक्सटेंशन नहीं है (कहते हैं। * .txt)। * .Txt does not के साथ संशोधित README काम करने लगते हैं
WanderingMind

@WanderingMind - यदि आप एक नया सवाल है ;-) साइट पर एक नया एक के रूप में यह कहें
SLM

3

आप फ़ाइल -execके findलिए जाँच करने के विकल्प का उपयोग कर सकते हैं , और फिर उन सभी परिणामों को प्रिंट कर सकते हैं जिनके लिए जाँच विफल हो जाती है।

find /path/to/base -mindepth 1 -maxdepth 1 -type d -exec test -e {}/README \; -o -print

3

की कोई जरूरत नहीं find। बस शेल का उपयोग करें:

for d in */; do [ -f "$d"README ] || printf '%s\n' "$d"; done
c/

आप इसे की जरूरत है पुनरावर्ती होने के लिए आपको (के लिए उपयोग कर सकते हैं bash, zshडिफ़ॉल्ट, उपयोग करके ऐसा कर सकते set -o globstarमें ksh93):

shopt -s globstar
for d in **/; do [ -f "$d"README ] || printf '%s\n' "$d"; done

(ध्यान दें कि डॉट-फाइलें डिफ़ॉल्ट रूप से बाहर रखी गई हैं)।


2

साथ zshऔर ग्लोब क्वालिफायर ( eस्ट्रिंग ):

print -rl -- *(/e_'[[ ! -f $REPLY/README ]]'_)

या

print -rl -- *(/^e_'[[ -f $REPLY/README ]]'_)

Dछिपी निर्देशिकाओं को शामिल करने के लिए जोड़ें :

print -rl -- *(D/e_'[[ ! -f $REPLY/README ]]'_)

/केवल निर्देशिकाओं का चयन करता है और e_'[[ ! -f $REPLY/README ]]'_आगे केवल उन निर्देशिका नामों का चयन करता है जिनके लिए उद्धरण कोड के बीच शेल कोड होता है true, जो कि प्रत्येक निर्देशिका नाम ( $REPLY) के लिए है कि ग्लोब का *(/)विस्तार होता है, यह चलता है [[ ! -f $REPLY/README ]]और परिणाम होने पर निर्देशिका का नाम रखता है true
दूसरा रूप ^e_'.....'_एक ही ग्लोब क्वालीफायर का उपयोग करता है, नकारात्मक (लेकिन इस बार सशर्त अभिव्यक्ति उपेक्षित नहीं है:) [[ -f $REPLY/README ]]


उपरोक्त केवल वर्तमान निर्देशिका में निर्देशिका नाम लौटाएगा।
यदि आप पुनरावर्ती खोज करना चाहते हैं (फिर से, छिपी निर्देशिकाओं को शामिल करने के लिए Dक्वालीफायर जोड़ें ):

print -rl ./**/*(/e_'[[ ! -f $REPLY/README ]]'_)

2

आंशिक रूप से, आप कर सकते हैं:

find . -type d -exec sh -c '
  for dir do
    [ -f "$dir/README" ] || printf "%s\n" "$dir"
  done' sh '{}' +

[ -f file ]यदि फ़ाइल मौजूद है और एक नियमित फ़ाइल (सिम्लिंक रिज़ॉल्यूशन के बाद) होने की पुष्टि की जाती है।

यदि आप परीक्षण करना चाहते हैं कि यह केवल (उस निर्देशिका में एक प्रविष्टि के रूप में) मौजूद है, तो इसके प्रकार की परवाह किए बिना, आपको इसकी आवश्यकता होगी:, [ -e file ] || [ -L file ]हालांकि ध्यान दें कि आपको उन परीक्षणों को करने के लिए निर्देशिका की खोज अनुमति की आवश्यकता है। आप [ -x "$dir" ]उन मामलों के लिए कुछ परीक्षण जोड़ना चाह सकते हैं जैसे:

find . -type d -exec sh -c '
  for dir do
    if [ -x "$dir" ]; then
      [ -f "$dir/README" ] || printf "%s\n" "$dir"
    else
      printf >&2 "Cannot tell for \"%s\"\n" "$dir"
    fi
  done' sh '{}' +

या दौड़ की स्थिति से बचने के लिए zsh:

find . -type d -exec zsh -c '
  zmodload zsh/system
  for dir do
    ERRNO=0
    if [ ! -f "$dir/README" ]; then
      if [ "$errnos[ERRNO]" = ENOENT ]; then
        printf "%s\n" "$dir"
      else
        syserror -p "ERROR: $dir/README: "
      fi
    fi
  done' zsh '{}' +

यह भी देखें कि मैं कैसे बताऊँ कि क्या एक नियमित फ़ाइल बैश में मौजूद नहीं है? इतने पर।

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