كيفية مقارنة الملفات ذات الأسماء نفسها في دليلين مختلفين باستخدام برنامج نصي Shell

StackOverflow https://stackoverflow.com/questions/119788

  •  02-07-2019
  •  | 
  •  

سؤال

قبل الانتقال إلى استخدام SVN، كنت أدير مشروعي ببساطة عن طريق الاحتفاظ بـ /develop/ الدليل وتحرير الملفات واختبارها هناك، ثم نقلها إلى المجلد /main/ الدليل.عندما قررت الانتقال إلى SVN، كنت بحاجة للتأكد من أن الدلائل كانت متزامنة بالفعل.

إذًا، ما هي الطريقة الجيدة لكتابة برنامج شل [ bash ] لمقارنة الملفات التي تحمل نفس الاسم بشكل متكرر في دليلين مختلفين؟

ملحوظة:أسماء الدليل المستخدمة أعلاه هي للعينات فقط.لا أوصي بتخزين الكود الخاص بك في المستوى الأعلى :).

هل كانت مفيدة؟

المحلول

يحتوي الأمر diff على خيار -r لمقارنة الأدلة بشكل متكرر:

diff -r /develop /main

نصائح أخرى

diff -rqu /develop /main

سيعطيك فقط ملخصًا للتغييرات بهذه الطريقة :)

إذا كنت تريد أن ترى فقط جديد/مفقود ملفات

diff -rqu /develop /main | grep "^Only

إذا كنت ترغب في الحصول عليها عارية:

diff -rqu /develop /main | sed -rn "/^Only/s/^Only in (.+?): /\1/p"

الفرق المتاح لدي يسمح باختلافات متكررة:

diff -r main develop

ولكن باستخدام برنامج شل النصي:

( cd main ; find . -type f -exec diff {} ../develop/{} ';' )

[قرأت في مكان ما أنه من الجيد الإجابة على أسئلتك، لذا إليك :) ]

لقد حاولت هذا، وعملت بشكل جيد

[/]$ cd /develop/
[/develop/]$ find | while read line; do diff -ruN "/main/$line" $line; done |less

يمكنك اختيار مقارنة ملفات محددة فقط [على سبيل المثال، ملفات .php فقط] عن طريق تحرير السطر أعلاه كـ

[/]$ cd /develop/
[/develop/]$ find -name "*.php" | while read line; do diff -ruN "/main/$line" $line; done |less

هل هناك أي أفكار أخرى؟

هنا مثال على نص خاص بي (فوضوي إلى حد ما)، dircompare.sh, ، والتي سوف:

  • فرز الملفات والأدلة في صفائف اعتمادًا على الدليل الذي توجد فيه (أو كليهما)، في مسارين متكررين
  • يتم فرز الملفات الموجودة في كلا الدليلين مرة أخرى في صفيفين، اعتمادًا على ما إذا كان diff -q ويحدد إذا كانوا مختلفين أم لا
  • لتلك الملفات التي diff المطالبات متساوية، وإظهار ومقارنة الطوابع الزمنية

نأمل أن يكون من المفيد - تحياتي!

تحرير 2:(في الواقع، إنه يعمل بشكل جيد مع الملفات البعيدة - كانت المشكلة هي عدم معالجة إشارة Ctrl-C أثناء عملية مختلفة بين الملف المحلي والبعيد، الأمر الذي قد يستغرق بعض الوقت؛تم تحديث البرنامج النصي الآن باستخدام مصيدة للتعامل مع ذلك - مع ترك التعديل السابق أدناه كمرجع):

يحرر:...باستثناء أنه يبدو أنه يتعطل الخادم الخاص بي لدليل ssh بعيد (والذي حاولت استخدامه عبر ~/.gvfs)...لذلك هذا ليس كذلك bash بعد الآن، ولكن أعتقد أن البديل هو الاستخدام rsync, ، إليك مثال:

$ # get example revision 4527 as testdir1
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/data@4527 testdir1

$ # get earlier example revision 2729 as testdir2
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/data@2729 testdir2

$ # use rsync to generate a list 
$ rsync -ivr --times --cvs-exclude --dry-run testdir1/ testdir2/
sending incremental file list
.d..t...... ./
>f.st...... CMakeLists.txt
>f.st...... MACCS.txt
>f..t...... SMARTS_InteLigand.txt
...
>f.st...... atomtyp.txt
>f+++++++++ babel_povray3.inc
>f.st...... bin2hex.pl
>f.st...... bondtyp.h
>f..t...... bondtyp.txt
...

لاحظ أن:

  • للحصول على ما سبق، يجب ألا تنسى الخطوط المائلة اللاحقة / في نهاية أسماء الدليل في rsync
  • --dry-run - محاكاة فقط، لا تقم بتحديث/نقل الملفات
  • -r - العودة إلى الدلائل
  • -v - مطول (لكن لا المتعلقة بمعلومات تغييرات الملف)
  • --cvs-exclude - يتجاهل .svn ملفات
  • -i - "--تفصيل-التغييرات:إخراج ملخص التغيير لجميع التحديثات"

هنا مقتطف قصير من man rsync الذي يوضح المعلومات التي أظهرها -i (على سبيل المثال، >f.st...... السلاسل أعلاه):

The  "%i"  escape  has a cryptic output that is 11 letters long.
The general format is like the string YXcstpoguax,  where  Y  is
replaced  by the type of update being done, X is replaced by the
file-type, and the other letters represent attributes  that  may
be output if they are being modified.

The update types that replace the Y are as follows:

o      A  < means that a file is being transferred to the remote
       host (sent).

o      A > means that a file is being transferred to  the  local
       host (received).

o      A  c  means that a local change/creation is occurring for
       the item (such as the creation  of  a  directory  or  the
       changing of a symlink, etc.).

...
The file-types that replace the X are: f for a file, a d  for  a
directory,  an  L for a symlink, a D for a device, and a S for a
special file (e.g. named sockets and fifos).

The other letters in the string above  are  the  actual  letters
that  will be output if the associated attribute for the item is
being updated or a "." for no change.  Three exceptions to  this
are:  (1)  a newly created item replaces each letter with a "+",
(2) an identical item replaces the dots with spaces, and (3)  an
....

غامض بعض الشيء بالفعل - ولكنه على الأقل يُظهر مقارنة الدليل الأساسي ssh.هتافات!

ستكون الإجابة الكلاسيكية (System V Unix). dircmp dir1 dir2, ، وهو عبارة عن برنامج نصي لشل يسرد الملفات الموجودة في dir1 ولكن ليس في dir2 أو في dir2 ولكن ليس في dir1 في البداية (الصفحة الأولى من الإخراج، من pr الأمر، بحيث يكون مرقّمًا بالعناوين)، متبوعًا بمقارنة كل ملف مشترك مع التحليل (كان الدليل نفسه، المختلف، هو النتائج الأكثر شيوعًا).

يبدو أن هذا في طور التلاشي - لدي إعادة تنفيذ مستقلة له متاحة إذا كنت في حاجة إليها.انها ليست علم الصواريخ (cmp هو صديقك).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top