linux diff टूल: संशोधित फ़ाइलों की सूची बनाएँ


14

मैं प्रोग्राम कमांड लाइन टूल्स का उपयोग करके संशोधित फाइलों की सूची कैसे बनाऊं? मैं किसी विशेष फ़ाइल (डेल्टा, पैच) के अंतर में दिलचस्पी नहीं रखता। मैं सिर्फ पिछले उत्पाद रिलीज की तुलना में नई या संशोधित फ़ाइलों की एक सूची रखना चाहता हूं। ताकि मैं एक नया उत्पाद अपडेट प्रकाशित कर सकूं।

अद्यतन: diff -qrबहुत आश्वस्त आउटपुट का उत्पादन नहीं करता है। आउटपुट को diff -qrभी संसाधित करने की आवश्यकता है। क्या कोई बेहतर तरीका है?


"सुविधाजनक" आउटपुट का एक उदाहरण क्या है?
मेंढक fro fro

जवाबों:


8

मुझे इसके लिए एक सरल तरीका मिला: rsync- पूर्वावलोकन मोड का उपयोग करें:

rsync -aHSvn --delete old_dir/ new-dir/

उस कमांड द्वारा "डिलीट की जाने वाली" के रूप में दिखाई जाने वाली फाइलें "नई" फाइलें होंगी। जिन अन्य को स्थानांतरित किया जाना है, वे किसी तरह से बदल गए हैं। अधिक विवरण के लिए rsync-man-page देखें।


13

आप उपयोग कर सकते हैं diff toool: विकल्प -q और -r देखना

-q  --brief
Output only whether files differ.

-r  --recursive
Recursively compare any subdirectories found.

उदाहरण:

diff -qr dir1 dir2

पूरी तरह से भयानक और अपठनीय उत्पादन, बकवास जानकारी के साथ बरबाद हो जाता है Only inजो निर्देशिका आदर्श प्रतियां होने पर भी प्रकट होता है। मुझे एक पुराने संशोधन के खिलाफ परिवर्तनों की तुलना करने की आवश्यकता थी, और संपूर्ण संशोधन को एक अलग निर्देशिका में डाउनलोड करने और तुलना करने के लिए मानक SVN टूल का उपयोग करने की आवश्यकता थी। यह एकमात्र रास्ता लगता है ...
हाई-एंजेल

3

diffutilsपैकेज एक भी शामिल है lsdiffउपकरण। बस diff -ulsdiff का आउटपुट पास करें :

diff -u --other-diff-options path1 path2 | lsdiff

अच्छा सुझाव, धन्यवाद। मेरे लिए patchutilsपैकेज में था (CentOS 5.x)।
स्टीव केहलेट

हां, उबंटू / डेबियन के लिए पैचअपिल पैकेज।
आर्टफ्लोरोबोट

1

मैं बस हर अपडेट के समय एक फाइल को छूता हूँ, और फिर आप उन फ़ाइलों को खोज सकते हैं जो तब से संशोधित थीं find /tree/location -newer /last/update/file -print


1

केवल उन फ़ाइलों का नाम लेने के लिए जिन्हें उन्होंने बदला है, मैं इस कमांड का उपयोग करता हूं:

diff -r dirt1 dir2 --brief | sed 's/^Only in \([^:]*\): /\1\//' | sed 's/^Files \(.*\) and .* differ/\1/'

यदि कुछ फ़ाइलों को ऑब्जेक्ट फ़ाइलों या लाइब्रेरी फ़ाइलों के रूप में बाहर करने की आवश्यकता है, तो आप उपयोग कर सकते हैं:

diff -r dirt1 dir2 --brief --exclude "*.o" --exclude "*.a" | sed 's/^Only in \([^:]*\): /\1\//' | sed 's/^Files \(.*\) and .* differ/\1/'

1

प्रोग्रामिक रूप से सबसे अच्छा समाधान जो मैं आ सकता था, की एक सूची बनाने के लिए rsync , सॉर्ट और साइज़ का उपयोग कर रहा हूँ :

(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq

मुझे इस उदाहरण के साथ समझाएं: हम दो डाकुविकी रिलीज की तुलना यह देखना चाहते हैं कि कौन सी फाइलें बदली गई थीं और कौन से नए बनाए गए थे।

हम टार्स को wget के साथ लाते हैं और उन्हें निर्देशिकाओं में निकालते हैं old/और new/:

wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz
mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1
mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1

Rsync चलाने से एक तरह से rsync और अलग-अलग शो की तुलना के रूप में नई बनाई गई फ़ाइलें याद आ सकती हैं:

rsync -rcn --out-format="%n" old/ new/

निम्नलिखित उत्पादन प्राप्त करता है:

VERSION
doku.php
conf/mime.conf
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php

केवल एक दिशा में rsync चलाने से नई बनाई गई फ़ाइलों की याद आती है और दूसरा रास्ता हटाई गई फ़ाइलों को मिस करने के लिए, अंतर के आउटपुट की तुलना करें:

diff -qr old/ new/

निम्नलिखित उत्पादन प्राप्त करता है:

Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ

दोनों तरीके से rsync चलाने और डुप्लिकेट को निकालने के लिए आउटपुट को छाँटने से पता चलता है कि निर्देशिका data/pages/playground/और फ़ाइल data/pages/playground/playground.txtशुरू में छूट गई थीं:

(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq

निम्नलिखित उत्पादन प्राप्त करता है:

VERSION
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php

rsync शोध तर्क के साथ चलाया जाता है:

  • -r "निर्देशिकाओं में फिर से आना",
  • -c समान आकार की फ़ाइलों की तुलना करने के लिए और केवल "चेकसम के आधार पर स्किप करें, न कि मॉड-टाइम और आकार",
  • -n "कोई परिवर्तन नहीं किए गए के साथ एक परीक्षण चलाने के लिए", और
  • --out-format="%n" "निर्दिष्ट FORMAT का उपयोग करके आउटपुट अपडेट", जो केवल फ़ाइल नाम के लिए "% n" है

rsyncदोनों दिशाओं के आउटपुट (फाइलों की सूची) को संयुक्त और क्रमबद्ध रूप से उपयोग किया जाता है sort, और फिर इस तरह की सूची को दो डुप्लिकेट को हटाकर संघनित किया जाता हैuniq



0

यह चाल हो सकती है:

compare_dirs()
{
    # Shows which files and directories exist in one directory but not both
    if [ $# -ne 2 ]
    then
        echo "Usage: compare_dirs dir1 dir2" >&2
        return 2
    fi
    for path
    do
        if [ ! -d "$path" ]
        then
            echo "Not a directory: $path" >&2
            return 1
        fi
    done
    comm -3 \
        <(cd -- "$1" && find . -printf '%P\0' | sort -z | quote_shell) \
        <(cd -- "$2" && find . -printf '%P\0' | sort -z | quote_shell)
}

0

आम तौर पर आप फ़ाइलों को किसी प्रकार के संस्करण नियंत्रण प्रणाली में डालते हैं जैसे कि सबवर्सन या गिट, क्योंकि वे आपके लिए यह बॉक्स से बाहर कर सकते हैं।

लेकिन आप dir1 पर लूप के साथ एक त्वरित स्क्रिप्ट कर सकते हैं और फिर dir2 में प्रत्येक फ़ाइल की तुलना करें। फ़ाइलों के अलग-अलग होने के लिए लूप फॉर एग्जिट कोड को भिन्न से देख सकता है।

शायद कुछ इस तरह:

for f in `(cd dir1 ; find .)`
do 
  diff $f ../dir2/$f
  if [ "$?" == "0" ]
  then 
    echo same
  else 
    echo diff: $f
  fi
done

नोट: लिपि का परीक्षण नहीं किया गया है, इसलिए उपरोक्त उदाहरण "बैड से प्रेरित स्यूडोकोड" है ...


चलो एक और ले जाओ, लेकिन गिट के साथ

साथ खेलने के लिए कुछ उदाहरण फ़ाइलें बनाएँ

mkdir -p dir1/test1/test11
mkdir -p dir1/test1/test12
mkdir -p dir1/test1/test13
echo "Test1" >> dir1/test1/test11/t1.txt
echo "Test2" >> dir1/test1/test12/t2.txt
echo "Test3" >> dir1/test1/test13/t3.txt

#And a dir to work in
mkdir gitdir

फिर dir दर्ज करें और dir1 आयात करें

cd gitdir/
git init .
cp -r ../dir1/* .
git add .
git commit -m 'dir1'

बाहर जाएं और dir1 को संशोधित करें (इसलिए यह आपका dir2 बन जाता है)

cd ..
echo "Test2" > dir1/test1/test11/t1.txt

फिर git dir में जाएं और नए dir को इम्पोर्ट करें

cd gitdir/
cp -r ../dir1/* .

अब पूछें कि परिवर्तन क्या है (स्थिति कमांड के साथ)

git status -s

आउटपुट परिवर्तनों के साथ एक सूची है, जो इस तरह दिखता है:

 M test1/test11/t1.txt

0

शायद आप कुछ अलग के साथ खुश होंगे। कोशिश करो git

इसे एक उदाहरण के रूप में करें:

mkdir a
cd a
git init
touch b
git add . && git commit -m "Empty file"
git status
echo c >> b
git status
git add . && git commit -m "Full file"
git status

gitआपके लिए आपकी फ़ाइलों को ट्रैक करेगा। कमांड git statusआपको उन सभी फाइलों को दिखाएगा जिन्हें अंतिम प्रतिबद्ध के बाद से संशोधित किया गया है।


0

यह rsync के समान है : यह दिखाएं कि गंतव्य पर नई फ़ाइल कब ओवरराइट की जानी है (बाद में पूछा गया, हालांकि डुप्लिकेट नहीं)।

जैसा कि प्रश्न में संकेत दिया गया है, "diff -q -r" को उपयोगी होने के लिए कुछ प्रसंस्करण की आवश्यकता हो सकती है। प्रश्न आउटपुट के रूप को निर्दिष्ट नहीं करता था; जवाब विभिन्न प्रकार की रिपोर्ट देते हैं।

rsyncइस उद्देश्य के लिए एक उपयोगी उपकरण है क्योंकि यह बहुत तेजी से है diff। हालाँकि, @nils द्वारा सुझाए गए समाधान पुराने / नए निर्देशिका पेड़ों के बीच वास्तविक अंतर की तुलना में कहीं अधिक क्रियात्मक है (और अधिक फ़ाइलों को सूचीबद्ध करता है)। उदाहरण के लिए, उस स्क्रिप्ट के खिलाफ तुलना करना जो मैंने उस उत्तर के लिए लिखा था, और उसी डेटा पर चल रहा था,

  • @ निल्स उत्तर में 605 लाइनें (जाहिर है क्योंकि इसमें निर्देशिका परिवर्तन शामिल हैं),
  • "diff -q -r" कई मिनटों तक चलने के बाद 352 लाइनें पैदा करता है, और
  • मेरी स्क्रिप्ट 252 लाइनें दिखाती है ( वास्तविक फ़ाइलें बदली गई, जोड़ी या हटा दी गईं)

नई फ़ाइलों के diffलिए ठीक से खाता बनाने के लिए , आपको विकल्प की आवश्यकता है (जो कि किसी भी सुझाए गए उत्तर में नहीं दिखता है)। हालाँकि, यह बाद के धीमे (परिमाण के आदेश) की तुलना में , बाद के उत्पादन में सुधार करने के लिए जाने का रास्ता लगता है।-Nrsync

आगे की पढाई


0

मैं हमेशा sha1sum (या यहां तक ​​कि md5sum के लिए आंशिक रहा हूं; इस संदर्भ में यह काफी सुरक्षित है)।

find . -type f -print0 | xargs -0 md5sum | sort -k2 > /tmp/before
# don't miss the "sort" in there; it's important

# (later)
find . -type f -print0 | xargs -0 md5sum | sort -k2 > /tmp/after
vimdiff /tmp/before /tmp/after
# or whatever diff tool you like, even "diff -u"

कभी-कभी - जैसे यदि आपके पास बहुत सारी फाइलें हैं, जिनका नाम बदल दिया गया है या उनके बारे में स्थानांतरित कर दिया गया है - पहले क्षेत्र पर छंटनी और फिर ऐसा करने से मदद मिल सकती है, लेकिन ज्यादातर समय यह काफी अच्छा होता है।

ध्यान दें कि, कुछ अन्य तरीकों की तुलना में, इसका यह लाभ है कि आपको "पहले" फ़ाइलों की एक प्रति रखने की आवश्यकता नहीं है; केवल md5sum आउटपुट फ़ाइल।

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