2012-03-07 9 views
11

मेरे पास निम्न आदेश हैं। जहां भी .user.log फ़ाइल मौजूद है, हमें मूल निर्देशिकाओं को मुद्रित करने की आवश्यकता है (iee hht और wee1।) यह कैसे किया जा सकता है?फाइलें खोजें और केवल अपनी मूल निर्देशिकाएं प्रिंट करें

$ cd /nfs//office/ && find . -name '.user.log' 
./hht/info/.user.log 
./wee1/info/.user.log 

उत्तर

11

क्या मुझे यहां कुछ याद आ रहा है। निश्चित रूप से यह सब regex और/या लूपिंग आवश्यक नहीं है, एक लाइनर नौकरी करेगा। इसके अलावा "$() में foo के लिए" पथ नामों में रिक्त स्थान होने पर समाधान विफल हो जाएंगे।

बस xargs साथ दो बार dirname उपयोग करते हैं, माता-पिता के माता पिता को पाने के लिए ...

# make test case 
mkdir -p /nfs/office/hht/info 
mkdir -p /nfs/office/wee1/info 
touch /nfs/office/hht/info/.user.log 
touch /nfs/office/wee1/info/.user.log 

# parent's parent approach 
cd /nfs//office/ && find . -name '.user.log' | xargs -I{} dirname {} | xargs -I{} dirname {} 

# alternative, have find print parent directory, so dirname only needed once... 
cd /nfs//office/ && find . -name ".user.log" -printf "%h\n" | xargs -I{} dirname {} 

उत्पादन

./hht 
./wee1 
+0

और क्या मैं परिणामस्वरूप निर्देशिका खोजने के अनुमतियों को ढूंढ सकता हूं। -नाम '.user_repo।लॉग '| xargs -i {} dirname {} | xargs -i {} dirname {} | xargs ll – Rajeev

+0

मान लीजिए कि आप "ls -lA" के लिए सामान्य रूप से उपयोग किए गए उपनाम हैं, फिर नहीं। xargs केवल उपनाम नहीं चलाएगा, उपनाम नहीं। हालांकि, आप इसके बजाय "xargs ls -lA" कर सकते हैं ... – Adam

+0

चेतावनी दी जानी चाहिए, 'xis' के लिए ध्वज' को बहिष्कृत के रूप में सूचीबद्ध किया गया है, अधिमानतः इसके बजाय '-I' ध्वज का उपयोग करें। –

3
for file in $(find /nfs/office -name .user.log -print) 
do 
    parent=$(dirname $(dirname $file)) 
    echo $parent 
done 

संपादित करें: क्षमा करें याद है कि आप दादा-दादी निर्देशिका चाहते हैं।

0
find /nfs/office -name '.user.log' | while read line 
do 
    echo $line | awk -F/ '{print $(NF-1),$NF}' 
done 
0

आप कुछ इस तरह कर सकता है:

cd /nfs/office/ && find . -name '.user.log' | xargs -n1 -I{} expr match {} '\(\.\(\/[^/]*\/\)\?\)' 

जहां xargs का उपयोग करता expr match बात यह है कि . साथ स्लेश वर्णों के बीच निर्देशिका के पहले मैच (/dir/) तक शुरू होता है निकालने के लिए।

sed का उपयोग कर के रूप में निम्नानुसार होगा एक वैकल्पिक संस्करण:

cd /nfs/office/ && find . -name 'file.txt' | sed -r 's|(\./([^/]*/)?).*|\1|' 
1

@trojanfoe सही विचार है; this इसे सुरक्षित रूप से किसी भी फ़ाइल नाम के साथ काम करने के लिए प्राप्त करने के लिए सिर्फ एक रास्ता है, और पाश के भीतर काफी किसी भी आदेश है:

while IFS= read -r -d '' -u 9 
do 
    echo "$(dirname -- "$(dirname -- "$REPLY")")" 
done 9< <(find "/nfs/office/" -name '.user.log' -print0) | sort -u 
:

while IFS= read -r -d '' -u 9 
do 
    echo "$(dirname -- "$(dirname -- "$REPLY")")" 
done 9< <(find "/nfs/office/" -name '.user.log' -print0) 

आप इसे केवल अद्वितीय नाम गूंज चाहते हैं

+0

कोई विशेष कारण आप एक अलग फ़ाइल वर्णनकर्ता का उपयोग कर रहे हैं? –

+0

यदि आप लूप के अंदर stdin के साथ कुछ करना चाहते हैं। यह उपरोक्त लिंक पर समझाया गया है। – l0b0

2

आप find की -printf कार्रवाई का प्रारूपण विकल्प आसानी से कर सकते हैं (देखें man find)।

cd /nfs//office/ && find . -name '.user.log' -printf "%h\n" 
./hht/info 
./wee1/info 

man page से:

Screenshot of find manpage

%h\n एक नई लाइन पर प्रत्येक फ़ाइल के लिए पथ प्रिंट होगा।

कृपया ध्यान दें कि -printf केवल जीएनयू है। यह मैकोज़ (बीएसडी सिस्टम) पर काम नहीं करेगा।

0
find -type f -exec bash -c 'echo "${1%/*}"' bash {} \; 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^