दो फाइलों की तुलना कैसे करें


83

तो मूल रूप से मैं जो करना चाहता हूं वह कॉलम द्वारा लाइन द्वारा दो फ़ाइल की तुलना करना है। मैं इसे कैसे पूरा कर सकता हूं?

File_1.txt:

User1 US
User2 US
User3 US

File_2.txt:

User1 US
User2 US
User3 NG

आउटपुट फाइल:

User3 has changed

11
उपयोगdiff "File_1.txt" "File_2.txt"
पंड्या

यह भी देखें: askubuntu.com/q/12473
पंड्या

जवाबों:


92

में देखो diffआदेश। यह एक अच्छा उपकरण है, और आप man diffअपने टर्मिनल में टाइप करके इसके बारे में सब पढ़ सकते हैं ।

आप जो कमांड करना चाहते हैं, diff File_1.txt File_2.txtवह दोनों के बीच के अंतर को आउटपुट करेगा और कुछ इस तरह दिखना चाहिए:

यहाँ छवि विवरण दर्ज करें

तीसरी कमांड से आउटपुट पढ़ने पर एक त्वरित टिप्पणी: 'एरो' ( <और >) लेफ्ट फाइल ( <) बनाम राइट फाइल ( >) बनाम राइट फाइल ( ) में बाईं ओर मौजूद फाइल के साथ क्या होता है पहले कमांड लाइन पर, इस मामले मेंFile_1.txt

इसके अतिरिक्त, आप 4 डी कमांड को देख सकते हैं कि क्या diff ... | tee Output_Fileयह परिणाम diffएक में से पाइप है tee, जो तब उस आउटपुट को एक फ़ाइल में डालता है, ताकि आप इसे बाद के लिए सहेज सकें, यदि आप इसे कंसोल पर उस दूसरे नंबर पर नहीं देखना चाहते हैं।


क्या यह अन्य फाइलें (जैसे चित्र) कर सकता है? या यह सिर्फ दस्तावेजों तक सीमित है?
ग्रेगरी ओपेरा

2
जहाँ तक मुझे पता है, यह पाठ फ़ाइलों तक सीमित है। कोड काम करेगा, क्योंकि यह अनिवार्य रूप से पाठ है, लेकिन किसी भी बाइनरी फाइलें (जो चित्र हैं) बस कबाड़ बाहर निकल जाएंगी। आप अगर वे ऐसा करने से समान हैं देखने के लिए तुलना कर सकते हैं: diff file1 file2 -s। यहाँ एक उदाहरण है: imgur.com/ShrQx9x
मिच

क्या आउटपुट को रंगीन करने का कोई तरीका है? मैं इसे केवल सीएलआई रखना चाहूंगा, लेकिन कुछ और ... मानव स्पर्श।
लजार लुजुबेनोविक 17

36

या फिर आप Meld Diff का उपयोग कर सकते हैं

मेल्ड आपको फाइलों, निर्देशिकाओं और संस्करण नियंत्रित परियोजनाओं की तुलना करने में मदद करता है। यह दोनों फ़ाइलों और निर्देशिकाओं की दो-और तीन-तरफ़ा तुलना प्रदान करता है, और कई लोकप्रिय संस्करण नियंत्रण प्रणालियों के लिए समर्थन है।

चलाकर स्थापित करें:

sudo apt-get install meld

आपका उदाहरण:

यहाँ छवि विवरण दर्ज करें

निर्देशिका की तुलना करें:

यहाँ छवि विवरण दर्ज करें

पाठ से भरा उदाहरण:

यहाँ छवि विवरण दर्ज करें


18

आप vimdiff का उपयोग कर सकते हैं ।

उदाहरण:

vimdiff  file1  file2

1
यह एक रंग है
जेक टोरंटो

इससे मुझे मदद मिली क्योंकि इससे पता चला कि मेरी पहली फ़ाइल की लाइन समाप्त हो रही थी dosऔर दूसरी बार में unix
LoMaPh

13

एफडब्ल्यूआईडब्ल्यू, मुझे पसंद है कि मुझे अलग से साइड-बाय-साइड आउटपुट के साथ क्या मिलता है

diff -y -W 120 File_1.txt File_2.txt

कुछ इस तरह देना होगा:

User1 US                            User1 US
User2 US                            User2 US
User3 US                          | User3 NG

10

आप कमांड का उपयोग कर सकते हैं cmp:

cmp -b "File_1.txt" "File_2.txt"

आउटपुट होगा

a b differ: byte 25, line 3 is 125 U 116 N

cmpdiffयदि आप चाहते हैं कि रिटर्न कोड की तुलना में बहुत तेज है ।
स्टीववेलावा

8

Meldवास्तव में एक महान उपकरण है। लेकिन आप diffuseदो फ़ाइलों की तुलना नेत्रहीन करने के लिए भी कर सकते हैं :

diffuse file1.txt file2.txt

यहाँ छवि विवरण दर्ज करें


7

Litteraly प्रश्न के साथ चिपका (फ़ाइल 1, फ़ाइल 2, आउटपुटफाइल के साथ "संदेश" बदल गया है) नीचे दी गई स्क्रिप्ट काम करती है।

स्क्रिप्ट को एक खाली फ़ाइल में कॉपी करें, इसे सहेजें compare.py, इसे निष्पादन योग्य बनाएं, इसे कमांड द्वारा चलाएं:

/path/to/compare.py <file1> <file2> <outputfile>

लिपी:

#!/usr/bin/env python

import sys
file1 = sys.argv[1]; file2 = sys.argv[2]; outfile = sys.argv[3]

def readfile(file):
    with open(file) as compare:
        return [item.replace("\n", "").split(" ") for item in compare.readlines()]

data1 = readfile(file1); data2 = readfile(file2)
mismatch = [item[0] for item in data1 if not item in data2]

with open(outfile, "wt") as out:
    for line in mismatch:
        out.write(line+" has changed"+"\n")

कुछ अतिरिक्त पंक्तियों के साथ, आप इसे या तो आउटपुटफाइल में या टर्मिनल पर प्रिंट कर सकते हैं, यह निर्भर करता है कि आउटपुट आउटपुट को परिभाषित किया गया है:

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

/path/to/compare.py <file1> <file2> <outputfile>

टर्मिनल विंडो पर प्रिंट करने के लिए:

/path/to/compare.py <file1> <file2> 

लिपी:

#!/usr/bin/env python

import sys

file1 = sys.argv[1]; file2 = sys.argv[2]
try:
    outfile = sys.argv[3]
except IndexError:
    outfile = None

def readfile(file):
    with open(file) as compare:
        return [item.replace("\n", "").split(" ") for item in compare.readlines()]

data1 = readfile(file1); data2 = readfile(file2)
mismatch = [item[0] for item in data1 if not item in data2]

if outfile != None:
        with open(outfile, "wt") as out:
            for line in mismatch:
                out.write(line+" has changed"+"\n")
else:
    for line in mismatch:
        print line+" has changed"

4

उपयोग करने का एक आसान तरीका है colordiff, जो व्यवहार करता है, diffलेकिन इसके आउटपुट को रंगीन करता है। रीडिंग डिफरेंसेस के लिए यह बहुत मददगार है। अपने उदाहरण का उपयोग करते हुए,

$ colordiff -u File_1.txt File_2.txt
--- File_1.txt  2016-12-24 17:59:17.409490554 -0500
+++ File_2.txt  2016-12-24 18:00:06.666719659 -0500
@@ -1,3 +1,3 @@
 User1 US
 User2 US
-User3 US
+User3 NG

जहां uविकल्प एक एकीकृत अंतर देता है। इस तरह से अलग रंग दिखता है:

यहाँ छवि विवरण दर्ज करें

colordiffचलाकर स्थापित करें sudo apt-get install colordiff


1
यदि आप चाहते हैं कि रंग मैं वास्तव में उपयोग करने के लिए आसान हो सकता है के रूप में निर्मित अंतर पाते हैं, श्री के जवाब में के रूप में
thomasrutter

2

अतिरिक्त जवाब

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

नीचे दी गई स्क्रिप्ट पर विचार करें, जहां आप दो फाइलों को तर्क के रूप में दे सकते हैं, और फाइल आपको बताएगी कि क्या वे समान हैं या नहीं।

#!/bin/bash

# Check if both files exist  
if ! [ -e "$1"  ];
then
    printf "%s doesn't exist\n" "$1"
    exit 2
elif ! [ -e "$2" ]
then
    printf "%s doesn't exist\n" "$2"
    exit 2
fi

# Get checksums of eithe file
file1_sha=$( sha256sum "$1" | awk '{print $1}')
file2_sha=$( sha256sum "$2" | awk '{print $1}')

# Compare the checksums
if [ "x$file1_sha" = "x$file2_sha" ]
then
    printf "Files %s and %s are the same\n" "$1" "$2"
    exit 0
else
    printf "Files %s and %s are different\n" "$1" "$2"
    exit 1
fi

नमूना रन:

$ ./compare_files.sh /etc/passwd ./passwd_copy.txt                                                                
Files /etc/passwd and ./passwd_copy.txt are the same
$ echo $?
0
$ ./compare_files.sh /etc/passwd /etc/default/grub                                                                
Files /etc/passwd and /etc/default/grub are different
$ echo $?
1

पुराना उत्तर

इसके अलावा commकमांड है, जो दो क्रमबद्ध फ़ाइलों की तुलना करता है, और 3 कॉलम्स में आउटपुट देता है: # 1 फाइल करने के लिए अद्वितीय आइटमों के लिए कॉलम 1, कॉलम # 2 के लिए अद्वितीय आइटमों के लिए कॉलम 2 और दोनों फाइलों में मौजूद आइटमों के लिए कॉलम 3।

कॉलम को दबाने के लिए आप स्विच -1, -2 और -3 का उपयोग कर सकते हैं। -3 का उपयोग करने से अलग-अलग लाइनें दिखाई देंगी।

बंद करो आप कार्रवाई में कमांड का स्क्रीनशॉट देख सकते हैं।

यहाँ छवि विवरण दर्ज करें

बस एक आवश्यकता है - उन्हें ठीक से तुलना करने के लिए फाइलों को क्रमबद्ध किया जाना चाहिए। sortउस उद्देश्य के लिए कमांड का उपयोग किया जा सकता है। Bellow एक और स्क्रीनशॉट है, जहाँ फ़ाइलों को क्रमबद्ध किया जाता है और फिर तुलना की जाती है। बाएं बेलोंग पर शुरू होने वाली लाइनें File_1 तक, कॉलम 2 पर शुरू होने वाली लाइनें केवल File_2 से संबंधित हैं

यहाँ छवि विवरण दर्ज करें


@DavidFoerster यह थोड़े मोबाइल :) हालांकि, अब हो गया पर संपादन करना मुश्किल है
सर्गी Kolodyazhnyy

2

गिट स्थापित करें और उपयोग करें

$ git diff filename1 filename2

और आपको अच्छे कलर्ड फॉर्मेट में आउटपुट मिलेगा

Git स्थापना

$ apt-get update
$ apt-get install git-core

2

colcmp.sh

प्रारूप में 2 फ़ाइलों में नाम / मूल्य जोड़े की तुलना करता है name value\n। लिखते हैं nameकरने के लिए Output_fileकरता है, तो बदल दिया है। साहचर्य सरणियों के लिए bash v4 + की आवश्यकता होती है ।

प्रयोग

$ ./colcmp.sh File_1.txt File_2.txt
User3 changed from 'US' to 'NG'
no change: User1,User2

आउटपुट फाइल

$ cat Output_File
User3 has changed

स्रोत (colcmp.sh)

cmp -s "$1" "$2"
case "$?" in
    0)
        echo "" > Output_File
        echo "files are identical"
        ;;
    1)
        echo "" > Output_File
        cp "$1" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A1\\[\\1\\]=\"\\2\"/" ~/.colcmp.array1.tmp.sh
        chmod 755 ~/.colcmp.array1.tmp.sh
        declare -A A1
        source ~/.colcmp.array1.tmp.sh

        cp "$2" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A2\\[\\1\\]=\"\\2\"/" ~/.colcmp.array2.tmp.sh
        chmod 755 ~/.colcmp.array2.tmp.sh
        declare -A A2
        source ~/.colcmp.array2.tmp.sh

        USERSWHODIDNOTCHANGE=
        for i in "${!A1[@]}"; do
            if [ "${A2[$i]+x}" = "" ]; then
                echo "$i was removed"
                echo "$i has changed" > Output_File
            fi
        done
        for i in "${!A2[@]}"; do
            if [ "${A1[$i]+x}" = "" ]; then
                echo "$i was added as '${A2[$i]}'"
                echo "$i has changed" > Output_File
            elif [ "${A1[$i]}" != "${A2[$i]}" ]; then
                echo "$i changed from '${A1[$i]}' to '${A2[$i]}'"
                echo "$i has changed" > Output_File
            else
                if [ x$USERSWHODIDNOTCHANGE != x ]; then
                    USERSWHODIDNOTCHANGE=",$USERSWHODIDNOTCHANGE"
                fi
                USERSWHODIDNOTCHANGE="$i$USERSWHODIDNOTCHANGE"
            fi
        done
        if [ x$USERSWHODIDNOTCHANGE != x ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi
        ;;
    *)
        echo "error: file not found, access denied, etc..."
        echo "usage: ./colcmp.sh File_1.txt File_2.txt"
        ;;
esac

व्याख्या

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

मूल फ़ाइल तुलना

cmp -s "$1" "$2"
case "$?" in
    0)
        # match
        ;;
    1)
        # compare
        ;;
    *)
        # error
        ;;
esac

cmp $ का मूल्य निर्धारित करेगा ? के रूप में इस प्रकार है :

  • 0 = फ़ाइलें मेल खाती हैं
  • 1 = फाइलें अलग हैं
  • 2 = त्रुटि

मैंने एक मामले का उपयोग करने के लिए चुना .. $ $ खाली करने के लिए esac बयान ? क्योंकि $ का मूल्य ? परीक्षण ([) सहित हर आदेश के बाद परिवर्तन

वैकल्पिक रूप से मैं $ का मूल्य रखने के लिए एक चर का उपयोग कर सकता था ? :

cmp -s "$1" "$2"
CMPRESULT=$?
if [ $CMPRESULT -eq 0 ]; then
    # match
elif [ $CMPRESULT -eq 1 ]; then
    # compare
else
    # error
fi

ऊपर मामला बयान के रूप में एक ही बात करता है। IDK जो मुझे बेहतर लगता है।

आउटपुट साफ़ करें

        echo "" > Output_File

ऊपर आउटपुट फ़ाइल को साफ करता है ताकि यदि कोई उपयोगकर्ता नहीं बदले, तो आउटपुट फ़ाइल खाली हो जाएगी।

मैं केस स्टेटमेंट्स के अंदर ऐसा करता हूं ताकि Output_file त्रुटि पर अपरिवर्तित रहे।

शेल स्क्रिप्ट में उपयोगकर्ता फ़ाइल की प्रतिलिपि बनाएँ

        cp "$1" ~/.colcmp.arrays.tmp.sh

मौजूदा उपयोगकर्ता के होम डायर पर उपर्युक्त प्रतियां File_1.txt से ऊपर ।

उदाहरण के लिए, यदि वर्तमान उपयोगकर्ता जॉन है, तो उपरोक्त cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh के समान होगा।

विशेष वर्ण से बचो

मूल रूप से, मैं पागल हूँ। मुझे पता है कि इन वर्णों को चर असाइनमेंट के हिस्से के रूप में स्क्रिप्ट में चलाने पर किसी बाहरी प्रोग्राम का विशेष अर्थ या निष्पादन हो सकता है:

  • `- बैक-टिक - एक प्रोग्राम और आउटपुट को निष्पादित करता है जैसे कि आउटपुट आपकी स्क्रिप्ट का हिस्सा था
  • $ - डॉलर संकेत - आमतौर पर एक चर उपसर्ग करता है
  • $ {} - अधिक जटिल चर प्रतिस्थापन के लिए अनुमति देता है
  • $ () - idk यह क्या करता है, लेकिन मुझे लगता है कि यह कोड निष्पादित कर सकता है

मुझे नहीं पता कि मैं बैश के बारे में कितना नहीं जानता। मुझे नहीं पता कि अन्य वर्णों के विशेष अर्थ क्या हो सकते हैं, लेकिन मैं उन सभी को पीछे छोड़ना चाहता हूं:

        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array1.tmp.sh

sed नियमित अभिव्यक्ति पैटर्न मिलान की तुलना में बहुत अधिक कर सकता है। स्क्रिप्ट पैटर्न "s / (ढूँढें) / / (बदलें) /" विशेष रूप से पैटर्न मैच करता है।

"S / (खोज) / (की जगह) / (संशोधक)"

अंग्रेजी में: किसी भी विराम चिह्न या विशेष वर्ण को कैप्चरिंग समूह 1 (\\ 1) के रूप में कैप्चर करें।

  • (बदलें) = \\\\\\\

अंग्रेजी में: बैकस्लैश के साथ सभी विशेष वर्णों को उपसर्ग करें

  • (संशोधक) = जी
    • जी = विश्व स्तर पर प्रतिस्थापित

अंग्रेजी में: यदि एक ही लाइन पर एक से अधिक मैच पाए जाते हैं, तो उन सभी को बदल दें

संपूर्ण स्क्रिप्ट पर टिप्पणी करें

        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.arrays.tmp.sh

ऊपर एक नियमित टिप्पणी का उपयोग करता है ~ / .colcmp.arrays.tmp.sh की हर पंक्ति को एक टिप्पणी टिप्पणी ( # ) के साथ उपसर्ग करने के लिए । मैं ऐसा इसलिए करता हूं क्योंकि बाद में मैं स्रोत कमांड का उपयोग करके ~ / .colcmp.arrays.tmp.sh को निष्पादित करने का इरादा रखता हूं और क्योंकि मुझे यकीन नहीं है कि फ़ाइल_1 . txt के पूरे प्रारूप को जानते हैं

मैं गलती से मनमाने कोड को अंजाम नहीं देना चाहता। मुझे नहीं लगता कि कोई करता है।

"S / (खोज) / (की जगह) /"

अंग्रेजी में: प्रत्येक पंक्ति को कैप्चर समूह 1 (\\ 1) के रूप में कैप्चर करें

  • (बदलें) = # \\ 1

अंग्रेजी में: प्रत्येक पंक्ति को एक पाउंड प्रतीक के साथ प्रतिस्थापित करें जिसके बाद उस पंक्ति को प्रतिस्थापित किया गया था

उपयोगकर्ता मान को A1 में बदलें [User] = "value"

        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A1\\[\\1\\]=\"\\2\"/" ~/.colcmp.arrays.tmp.sh

ऊपर इस लिपि का मूल है।

  • इसे परिवर्तित करें: #User1 US
    • इसके लिए: A1[User1]="US"
    • या यह: A2[User1]="US"(दूसरी फ़ाइल के लिए)

"S / (खोज) / (की जगह) /"

अंग्रेजी में:

  • आवश्यकता है लेकिन प्रमुख टिप्पणी पात्रों को अनदेखा करें (#)
  • प्रमुख व्हाट्सएप को अनदेखा करें
  • कैप्चर समूह 1 (\\ 1) के रूप में पहला शब्द कैप्चर करें
  • एक स्थान (या टैब, या व्हाट्सएप) की आवश्यकता होती है
    • क्योंकि यह एक समान संकेत के साथ प्रतिस्थापित किया जाएगा
    • यह किसी भी कब्जा समूह का हिस्सा नहीं है, और क्योंकि
    • (बदलें) पैटर्न कैप्चर समूह 1 और कैप्चर ग्रुप 2 के बीच एक समान चिह्न डालता है
  • कैप्चर ग्रुप 2 के रूप में बाकी लाइन कैप्चर करें

  • (बदलें) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"

    • A1 \\ [- शाब्दिक वर्ण A1[नामक सरणी में सरणी असाइनमेंट शुरू करने के लिएA1
    • \\ 1 = कैप्चर ग्रुप 1 - जिसमें प्रमुख हैश (#) शामिल नहीं है और इसमें प्रमुख व्हाट्सएप शामिल नहीं है - इस मामले में कैप्चर ग्रुप 1 का उपयोग बैश साहचर्य सरणी में नाम / मान जोड़ी के नाम को सेट करने के लिए किया जा रहा है।
    • \\] = \ "= शाब्दिक वर्ण ]="
      • ]= बंद सरणी असाइनमेंट जैसे A1[उपयोगकर्ता 1 ]="यूएस"
      • = = असाइनमेंट ऑपरेटर उदाहरण चर = मान
      • " = रिक्त स्थान कैप्चर करने के लिए मूल्य उद्धृत करें ... हालांकि अब जब मैं इसके बारे में सोचता हूं, तो कोड को उस बैकस्लैश के ऊपर भी छोड़ देना आसान हो जाता है ताकि अंतरिक्ष वर्णों को भी बैकलैश किया जा सके।
    • \\ 1 = कब्जा समूह 2 - इस मामले में, नाम / मूल्य जोड़ी का मूल्य
    • "" रिक्त स्थान पर कब्जा करने के लिए उद्धरण मूल्य बंद करना

अंग्रेजी में: प्रारूप में प्रत्येक पंक्ति को #name valueसरणी असाइनमेंट ऑपरेटर के साथ प्रारूप में बदलेंA1[name]="value"

निष्पादन योग्य बनाएं

        chmod 755 ~/.colcmp.arrays.tmp.sh

सरणी स्क्रिप्ट फ़ाइल को निष्पादन योग्य बनाने के लिए ऊपर chmod का उपयोग करता है ।

मुझे यकीन नहीं है कि यह आवश्यक है।

सहयोगी ऐरे की घोषणा करें (bash v4 +)

        declare -A A1

कैपिटल-ए इंगित करता है कि घोषित चर एसोसिएटेड सरणियां होंगी ।

यही कारण है कि स्क्रिप्ट को bash v4 या अधिक से अधिक की आवश्यकता होती है।

हमारे ऐरे वेरिएबल असाइनमेंट स्क्रिप्ट को निष्पादित करें

        source ~/.colcmp.arrays.tmp.sh

हमने पहले से ही:

  • की लाइनों से हमारे फ़ाइल परिवर्तित User valueकी लाइनों के लिए A1[User]="value",
  • इसे निष्पादन योग्य बनाया (शायद), और
  • एक सहयोगी सरणी के रूप में A1 घोषित ...

ऊपर हम मौजूदा शेल में इसे चलाने के लिए स्क्रिप्ट का स्रोत हैं । हम ऐसा करते हैं ताकि हम स्क्रिप्ट द्वारा निर्धारित किए गए चर मानों को रख सकें। यदि आप स्क्रिप्ट को सीधे निष्पादित करते हैं, तो यह एक नया शेल बनाता है, और जब नया शेल बाहर निकलता है या कम से कम मेरी समझ में आता है, तो चर मान खो जाता है।

यह एक फंक्शन होना चाहिए

        cp "$2" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A2\\[\\1\\]=\"\\2\"/" ~/.colcmp.array2.tmp.sh
        chmod 755 ~/.colcmp.array2.tmp.sh
        declare -A A2
        source ~/.colcmp.array2.tmp.sh

हम $ 1 और A1 के लिए वही काम करते हैं जो हम $ 2 और A2 के लिए करते हैं । यह वास्तव में एक समारोह होना चाहिए। मुझे लगता है कि इस बिंदु पर यह स्क्रिप्ट काफी भ्रमित कर रही है और यह काम करती है, इसलिए मैं इसे ठीक नहीं करने जा रहा हूं।

निकाले गए उपयोगकर्ताओं का पता लगाएं

        for i in "${!A1[@]}"; do
            # check for users removed
        done

सहयोगी सरणी कुंजियों के माध्यम से ऊपर छोरों

            if [ "${A2[$i]+x}" = "" ]; then

ऊपर वैरिएबल प्रतिस्थापन का उपयोग करता है, जो किसी ऐसे मान के बीच अंतर का पता लगाने के लिए है जो एक चर बनाम स्पष्ट रूप से शून्य लंबाई स्ट्रिंग के लिए सेट किया गया है।

जाहिरा तौर पर, यह देखने के लिए बहुत सारे तरीके हैं कि क्या एक चर सेट किया गया है । मैंने सबसे अधिक वोटों के साथ एक को चुना।

                echo "$i has changed" > Output_File

उपर्युक्त उपयोगकर्ता को $ i को Output_File में जोड़ता है

उपयोगकर्ताओं को पता लगाया या परिवर्तित किया गया

        USERSWHODIDNOTCHANGE=

ऊपर एक चर को साफ करता है ताकि हम उन उपयोगकर्ताओं पर नज़र रख सकें जो नहीं बदले थे।

        for i in "${!A2[@]}"; do
            # detect users added, changed and not changed
        done

सहयोगी सरणी कुंजियों के माध्यम से ऊपर छोरों

            if ! [ "${A1[$i]+x}" != "" ]; then

ऊपर चर विकल्प का उपयोग करता है यह देखने के लिए कि क्या चर सेट किया गया है

                echo "$i was added as '${A2[$i]}'"

क्योंकि $ i , सरणी कुंजी (उपयोगकर्ता नाम) $ A2 [$ i] है, इसे वर्तमान उपयोगकर्ता से संबंधित मान File_2.txt से वापस करना चाहिए ।

उदाहरण के लिए, यदि $ i है User 1 , ऊपर के रूप में पढ़ता $ {ए 2 [USER1]}

                echo "$i has changed" > Output_File

उपर्युक्त उपयोगकर्ता को $ i को Output_File में जोड़ता है

            elif [ "${A1[$i]}" != "${A2[$i]}" ]; then

चूँकि $ i , सरणी कुंजी (उपयोगकर्ता नाम) $ A1 है [$ i] को फ़ाइल_1 . txt से वर्तमान उपयोगकर्ता के साथ जुड़े मूल्य को वापस करना चाहिए , और $ A2 [$ i] को File_2.txt से मान वापस करना चाहिए ।

उपरोक्त दोनों फाइलों से उपयोगकर्ता $ i के लिए जुड़े मूल्यों की तुलना करता है ।

                echo "$i has changed" > Output_File

उपर्युक्त उपयोगकर्ता को $ i को Output_File में जोड़ता है

                if [ x$USERSWHODIDNOTCHANGE != x ]; then
                    USERSWHODIDNOTCHANGE=",$USERSWHODIDNOTCHANGE"
                fi
                USERSWHODIDNOTCHANGE="$i$USERSWHODIDNOTCHANGE"

ऊपर उन उपयोगकर्ताओं की अल्पविराम से अलग की गई सूची बनाता है जो नहीं बदले। ध्यान दें कि सूची में कोई स्थान नहीं हैं, अन्यथा अगले चेक को उद्धृत करना होगा।

        if [ x$USERSWHODIDNOTCHANGE != x ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi

ऊपर का मूल्य रिपोर्ट $ USERSWHODIDNOTCHANGE लेकिन में एक मूल्य है ही अगर $ USERSWHODIDNOTCHANGE । जिस तरह से यह लिखा गया है, $ USERSWHODIDNOTCHANGE में कोई स्थान नहीं हो सकता है। यदि इसे रिक्त स्थान की आवश्यकता होती है, तो ऊपर निम्नानुसार लिखा जा सकता है:

        if [ "$USERSWHODIDNOTCHANGE" != "" ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.