फ़ोल्डर तुलना


10

मेरे पास समान सबफ़ोल्डर संरचनाओं के साथ दो फ़ोल्डर हैं, जिनकी मैं तुलना करना चाहूंगा। उदाहरण के लिए:

A 
├── child-1
├── child-2
├── child-3
├── child-4
├── child-5

तथा

B 
├── child-1-some-text
├── child-2-more-text
├── child-3-nothing
├── child-6-random-text
├── child-7-more-random-text

मैं उन सभी सबफ़ोल्डर्स को सूचीबद्ध करना चाहूंगा, Aजिसमें से एक सबफ़ोल्डर के लिए उपसर्ग हैं Bऔर Bसाथ ही संबंधित सबफ़ोल्डर्स को भी सूचीबद्ध कर सकते हैं । अपेक्षित आउटपुट है

child-1 -- child-1-some-text
child-2 -- child-2-more-text
child-3 -- child-3-nothing

एक द्वितीयक आवश्यकता: यदि कई में मेल खाता है B, तो उसे एक त्रुटि / चेतावनी देनी चाहिए।

मेरा समाधान :

cd A
for f in `ls -d */`; 
do
    cd B;
    new_dirs=(`ls -1d $f*`);
    cd -;
    if [ ${#new_dirs[@]} -eq 0 ]
    then
        ## DO_Nothing
        continue;
    elif  [ ${#new_dirs[@]} -gt 1 ]
    then
        echo "Multiple matches to $f";
        continue;
    else
        echo "Unique Match found to $f -- ${new_dirs[0]}";
        continue;
    fi;    
done

मुसीबत:

उन मानों के लिए $f, जिनमें कोई संबंधित सबफ़ोल्डर नहीं है B, सरणी निर्माण मुझे एक त्रुटि दे रहा है। उदाहरण के लिए:

ls: 'child-4 *' तक नहीं पहुंच सकता: ऐसी कोई फ़ाइल या निर्देशिका नहीं

सवाल

  • इन त्रुटियों से कैसे छुटकारा पाएं?
  • क्या लक्ष्य प्राप्त करने का बेहतर तरीका है, फिर मेरे कोड में?

अग्रिम में धन्यवाद!


4
एक लगभग काम कर समाधान प्रदान करने के लिए +1!
user5325

यह आपके विशिष्ट प्रश्न का उत्तर नहीं है, लेकिन आप diff -rq DIR1 DIR2न केवल निर्देशिका संरचना, बल्कि फ़ाइल सामग्री की तुलना करने के लिए उपयोग कर सकते हैं।
jrw32982

जवाबों:


10

बेहतर तरीका है

तोता मत करोls ; इसके बजाय ग्लब्स का उपयोग करें। वास्तव में आप पहले से ही ग्लब्स का उपयोग कर रहे हैं, बस उन्हें लपेटकर ls, जो व्यर्थ है। nullglobजब कोई मैच न हो तो आपको बस चालू करना होगा।

इसके अलावा परहेज cdचीजों को सरल करता है।

#!/bin/bash

shopt -s nullglob

dir1=A
dir2=B

for dir in "$dir1"/*/; do
    basename="$(basename -- "$dir")"
    dirs_match=( "$dir2/$basename"*/ )
    case ${#dirs_match[@]} in
    0)
        ;;
    1)
        echo "Unique match for $dir: ${dirs_match[*]}"
        ;;
    *)
        echo "Multiple matches for $dir: ${dirs_match[*]}" >&2
        ;;
    esac
done

आउटपुट:

Unique match for A/child-1/: B/child-1-some-text/
Unique match for A/child-2/: B/child-2-more-text/
Multiple matches for A/child-3/: B/child-3-nothing/ B/child-3-something/

मैंने B/child-3-somethingद्वितीयक आवश्यकता का परीक्षण करने के लिए जोड़ा । यह परीक्षण के लिए निर्देशिका संरचना बनाता है:

mkdir -p A/child-{1..5} B/child-{1-some-text,2-more-text,3-nothing,3-something,6-random-text,7-more-random-text}

वैसे, शेल स्क्रिप्ट में समस्याओं को खोजने के लिए शेलचेक बहुत उपयोगी है।


ShellCheck.net दिलचस्प है, क्या आपको पता है कि यह सब कुछ अपने सर्वर पर अपलोड करता है, या यह सब स्थानीय स्तर पर किया जाता है? बस दर्ज जानकारी की गोपनीयता के बारे में सोच रहा था। [ shellcheckपैकेज स्थापित करना सबसे सुरक्षित होगा]
Xen2050

@ Xen2050 साइट पर रहते हुए मेरे इंटरनेट को बंद करने की कोशिश की, और यह अपलोड करने के लिए लगता है। मुझे लगता है कि यह इसे नहीं रखता है, लेकिन निश्चित नहीं है। और हाँ पैकेज अच्छा है; मैं एक एटम प्लगइन का उपयोग करता हूं जो इसका उपयोग करता है।
वेजेंड्रिया

सुझाव के लिए धन्यवाद। और यह भी इशारा करने के लिए धन्यवाद के टन ShellCheck। मैं उस हिस्से से प्यार करता था जहाँ यह न केवल आपको आपकी त्रुटियाँ बताता है, बल्कि सुझाव भी देता है! @ Xen2050, अपलोडिंग भाग के बारे में, मैंने अभी shellcheckउपयोग किया aptऔर फिर अक्षम नेटवर्क को स्थापित किया । यह बिना इंटरनेट के काम करने लगता है ।
माइक वीडीसी

2

lsगैर-मौजूद फ़ोल्डर पर कॉल करना आपके द्वारा सामना किए गए त्रुटि संदेश को फेंकता है। आसान तरीका सिर्फ इस के साथ अपनी स्क्रिप्ट में लाइन 5 बदल कर भी इस अनदेखी करने के लिए है: new_dirs=(`ls -1d $f* 2> /dev/null`);


क्या आपने इसका परीक्षण किया है? Stderr को डिफ़ॉल्ट रूप से नजरअंदाज किया जा रहा है, जब मैं t=(`echo ok; echo err 1>&2`)$ t (या ${t[@]}) चलाता हूं तो केवल ओके होता है, गलत तरीके से टर्मिनल में देखा जाता है, लेकिन वैसे भी सहेजा नहीं गया है। या मेरे परीक्षण के बारे में कुछ अजीब है?
2220 पर Xen2050
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.