निर्देशिकाएं ढूंढें, जहां विशिष्ट समाप्ति वाली फाइलें गायब हैं


10

मैं सभी निर्देशिकाओं को प्रदर्शित करना चाहता हूं, जिसमें विशिष्ट फ़ाइल समाप्त होने वाली फाइलें शामिल नहीं हैं। इसलिए मैंने निम्नलिखित कोड का उपयोग करने की कोशिश की:

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

इस उदाहरण में मैं सभी निर्देशिकाओं को प्रदर्शित करना चाहता था, जिसमें अंत के साथ फाइलें नहीं हैं .ENDING, लेकिन यह काम नहीं करता है।

मेरी गलती कहाँ है?


यह सूची निर्देशिकाओं का डुप्लिकेट नहीं है जिसमें फ़ाइल शामिल नहीं है क्योंकि यह प्रश्न वाइल्डकार्ड के साथ सौदा नहीं करता है।
क्रिस्टियन सियुपिटु

जवाबों:


7

यहाँ तीन चरणों में एक समाधान है:

temeraire:tmp jenny$ find . -type f -name \*ENDING -exec dirname {} \; |sort -u > /tmp/ending.lst
temeraire:tmp jenny$ find . -type d |sort -u > /tmp/dirs.lst
temeraire:tmp jenny$ comm -3 /tmp/dirs.lst /tmp/ending.lst 

2
बैश शेल का उपयोग करने पर अस्थायी फ़ाइलों के बिना वन-लाइनर:comm -3 <(find . -type f -name \*ENDING -exec dirname {} \; |sort -u) <(find . -type d |sort -u)
क्रिस्टियान सियुपिटु

4

ये रहा!

#!/usr/bin/env python3
import os

for curdir,dirnames,filenames in os.walk('.'):
  if len(tuple(filter(lambda x: x.endswith('.ENDING'), filenames))) == 0:
    print(curdir)

या वैकल्पिक रूप से (और अधिक pythonic):

#!/usr/bin/env python3
import os

for curdir,dirnames,filenames in os.walk('.'):
    # Props to Cristian Cliupitu for the better python
    if not any(x.endswith('.ENDING') for x in filenames):
        print(curdir)

बोनस डीएलसी सामग्री!

(अधिकतर) खोज कमांड का सही संस्करण:

find . -type d \! -exec bash -c 'set nullglob; test -f "{}"/*.ENDING' \; -print

मुझे लगता है कि खोज समाधान विफल रहता है test: ...: binary operator expectedअगर *.ENDINGएक निर्देशिका में कई फाइलें हैं ।
क्रिस्टियन सियुपिटु

next(filter(lambda x: x.endswith('.ENDING'), filenames))जनरेटर की समझ का उपयोग करके भी लिखा जा सकता है next(x for x in filenames if x.endswith('.ENDING'))
क्रिस्टियन सियुपिटु

@CristianCiupitu: सत्य: खोज कमांड हैकरी है और वास्तव में पूरी तरह से परीक्षण नहीं किया गया है। जनरेटर की समझ - हाँ, यह करने के लिए एक और अच्छा तरीका है।
मिकीबी

1
मुझे लगता है कि एक भी अच्छा समाधान if not any(x.endswith('.ENDING') for x in filenames)इस तथ्य के आधार पर उपयोग करना होगा कि कोई Falseखाली पुनरावृत्ति के लिए रिटर्न ।
क्रिस्टियन सियुपिटु

3

शेल का विस्तार होता है *, लेकिन आपके मामले में कोई शेल शामिल नहीं है, बस खोज द्वारा निष्पादित परीक्षण कमांड । इसलिए जिस फाइल के अस्तित्व का परीक्षण किया जाता है, उसका नाम शाब्दिक है ।*.ENDING

इसके बजाय आपको कुछ इस तरह का उपयोग करना चाहिए:

find . -type d \! -execdir sh -c 'test -e {}/*.ENDING' \; -print

इस में परिणाम होगा का विस्तार *.ENDINGजब परीक्षण निष्पादित किया जाता है।

स्रोत: UX.SE पर ग्लोबिंग खोजें


काम नहीं करता। मुझे निम्न त्रुटि मिलती है: sh: -c: line 0: syntax error near unexpected token ('``। मेरी निर्देशिका के नाम में' xyz (dfdf) 'प्रारूप है। वास्तव में इसकी कैलिबर लाइब्रेरी है।
बांस

1
जब मैं इसे आज़माता हूं, तो मुझे sh: line 0: test: foo1/bar.ENDING: binary operator expectedनिर्देशिका मिलती है जिसमें अंत के साथ एक फ़ाइल होती है ENDING
जेनी डी

यह मेरे लिए सादे a.ENDING फ़ाइलनाम के साथ काम करने लगता है
user9517

मेरे पास निम्नलिखित परीक्षण निर्देशिका संरचना है: परीक्षण-> परीक्षण (परीक्षण) -> test.ending इस कोड का उपयोग करने के बाद मुझे sh: -c: line 0: syntax error near unexpected token ('श: -c: पंक्ति 0:' परीक्षण-परीक्षण (परीक्षण) / * समाप्त हो रहा है ')। / परीक्षण (परीक्षण) `। लेकिन जब मैं बदल जाता हूं। .xyz में। मुझे एक ही परिणाम मिलता है। इसका कारण यह है कि मेरे पास निर्देशिका नाम के रूप में कड़वाहट है, ठीक है? मैं इसे कैसे ठीक कर सकता हूं?
बांस

3
@ बम्बो मैं शेल उपयोगिताओं के साथ हार मानूंगा और इस बिंदु पर एक अलग समाधान ढूंढूंगा।
user9517

2

डेनिस नोल्टे और मिकीबी के उत्तरों से प्रेरित होकर , मैं इस समाधान के साथ आया:

find . -type d                                                           \
  \! -exec bash -c 'shopt -s failglob; echo "{}"/*.ENDING >/dev/null' \; \
  -print 2>/dev/null

यह इस तथ्य पर आधारित काम करता है कि

यदि फेलग्लोब शेल विकल्प सेट किया गया है, और कोई मिलान नहीं मिला है, तो एक त्रुटि संदेश मुद्रित होता है और कमांड निष्पादित नहीं होता है।

वैसे, यही कारण है कि stderr को पुनर्निर्देशित किया गया था /dev/null


1

मैं इसे व्यक्तिगत रूप से पर्ल में करूँगा

#!/usr/bin/perl

use strict;
use warnings;

use File::Find;


#this sub is called by 'find' on each file it traverses. 
sub checkdir {
    #skip non directories. 
    return unless ( -d $File::Find::name );

    #glob will return an empty array if no files math - which evaluates as 'false'
    if ( not glob ( "$File::Find::name/*.ENDING" ) ) {
        print "$File::Find::name does not contain any files that end with '.ENDING'\n";
    }
}

#kick off the search on '.' - set a directory path or list of directories to taste.
#  - you can specify multiple in a list if you so desire. 
find (  \&checkdir, "." );

चाल करना चाहिए (मेरे बहुत ही सरल परीक्षण मामले पर काम करता है)।


0

Heres एक लाइनर पाते हैं।

find ./ -type d ! -regex '.*.ENDING$' -printf "%h\n" | sort -u

संपादित करें : उफ़, या तो काम नहीं करेगा।


यह काम नहीं करता क्योंकि आप निर्देशिकाओं के नाम का परीक्षण कर रहे हैं, न कि उनके अंदर की फाइलों का।
क्रिस्टियन सियुपिटु

मैंने इसे एक और कोशिश दी है। बुरी तरह से
मैथ्यू इफ

0
find . -type d '!' -exec sh -c 'ls -1 "{}"|egrep -q "*ENDING$"' ';' -print
  • q उदा में चुप के लिए है

  • egrepआप अपने साथ आवश्यक रेगीज़ स्वैप कर सकते हैं

  • ls -1 "{}" फ़ाइल नामों को खोज आदेश से आउटपुट करता है

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