سؤال كيف تتجاهل أسماء ملفات معينة باستخدام "find"؟


أحد أوامر BASH المفضلة هي:

find . -name '*.*' -exec grep 'SearchString' {} /dev/null \;

الذي يبحث في محتويات جميع الملفات الموجودة أسفل الدليل الحالي للبحث المحدد في SearchString. كمطور ، هذا قد يكون في متناول اليد في بعض الأحيان.

نظرًا لمشروعي الحالي ، وبنية كود البرمجة الخاصة بي ، فإنني أرغب في جعل أمر BASH هذا أكثر تقدمًا من خلال عدم البحث عن أي ملفات موجودة في أو تحت دليل يحتوي على ".svn" ، أو أي ملفات ينتهي بـ ".html"

صفحة MAN للعثور على نوع من الخلط بين لي رغم ذلك. حاولت استخدام -Bune ، وأعطاني سلوك غريب. في محاولة لتخطي صفحات .html فقط (للبدء) ، حاولت:

find . -wholename './*.html' -prune -exec grep 'SearchString' {} /dev/null \;

ولم أحصل على السلوك الذي كنت أتوقعه. أعتقد أنني قد أفتقد نقطة المني. هل يمكن أن تساعدني يا رفاق؟

شكر


112
2018-03-05 23:28


الأصل


لمعلوماتك فقط: find ليس أمر bash مضمّن ولكن برنامج منفصل - WakiMiko
يمكنك البحث داخل الملف مع grep -rl 'SearchString' - emanuele
emanuele مرحبا ، مرحبا بكم في SuperUser (وشبكة كومة الصرف). هذا سؤال طرحته ، وتمت الإجابة عليه ، منذ سنتين ونصف. عادةً ، إذا كنت ترغب في إضافة إجابة على السؤال ، فالرجاء القيام بذلك عن طريق التمرير إلى الأسفل والرد عليه ، بدلاً من التعليق. بما أن هذا السؤال لديه بالفعل إجابة مقبولة (التي تحتوي على علامة الاختيار الخضراء) ، فمن غير المحتمل أن تحظى إجابتك بالكثير من الاهتمام. لمعلوماتك. - Cody S
مرحباً ، إنه ليس إجابة لسؤالك. إنه مجرد تلميح ، كما ذكرت في الديباجة هذا الاستخدام find للبحث داخل الملف. - emanuele
FWIW، -name '*.*' لا يجد الكل الملفات: فقط مع . في أسمائهم (استخدام *.* عادة ما يكون DOS-ism ، بينما في يونكس ، عادة ما تستخدم فقط * من أجل هذا). لمطابقة جميعهم حقًا ، ما عليك سوى إزالة الحجة تمامًا: find . -exec .... أو إذا كنت تريد فقط تطبيق grep على الملفات (والانتقال إلى الدلائل) ، فافعل ذلك find . -type f -exec .... - Stefan


الأجوبة:


يمكنك استخدام ميزة negate (!) للبحث عن عدم مطابقة الملفات بأسماء محددة:

find . ! -name '*.html' ! -path '*.svn*' -exec grep 'SearchString' {} /dev/null \;

إذا كان الاسم ينتهي بـ. html أو يحتوي على .svn في أي مكان في المسار ، فلن يتطابق ، وبالتالي لن يتم تنفيذ exec.


159
2018-03-06 00:40



يجب أن أظل تحديد اسم ".في مكان ما هناك؟ هل سأفعل ذلك من قبل أم بعد النفي؟ - Cody S
كان نيتك *.* المباراة للتأكد من مطابقة الملفات فقط التي تحتوي على .؟ البحث سوف تطابق جميع الملفات في حالة عدم وجود name التوجيه ، لذلك فإن ما سبق سيطابق كل شيء ما عدا html و svn - Paul
أعتقد أنك تريد -wholename '*.svn*' عوضا عن -name. - fuenfundachtzig
نعم ، ذلك ، حتى أن .svn يتم استبعاد الدلائل من نتائج البحث. - fuenfundachtzig
Noumenon ! -name '.' يجب استبعاد . من نتائج البحث. - Paul


لقد واجهت نفس المشكلة لفترة طويلة ، وهناك العديد من الحلول التي يمكن تطبيقها في المواقف المختلفة:

  • ack-grep هو نوع من "المطور" grep" التي بشكل افتراضي يتخطى أدلة التحكم الإصدار والملفات المؤقتة. ال man تشرح الصفحة كيفية البحث في أنواع ملفات محددة فقط وكيفية القيام بذلك حدد بنفسك.
  • grepالخاصة --exclude و --exclude-dir خيارات يمكن استخدامها بسهولة بالغة لتخطي الملف اباريز و غير مرتبطة الدلائل (لا مغالط للدلائل ، لسوء الحظ).
  • find . \( -type d -name '.svn' -o -type f -name '*.html' \) -prune -o -print0 | xargs -0 grep ... يجب أن تعمل ، ولكن الخيارات المذكورة أعلاه ربما تكون أقل من المتاعب على المدى الطويل.

9
2018-03-06 13:54





ما يلي find الأمر يفعل الدلائل prune أسماؤها يحتوي  .svn، على الرغم من أنه لا ينزل إلى الدليل ، تتم طباعة اسم المسار المحذوف ... (-name '*.svn' هو السبب!) ..

يمكنك تصفية أسماء الأدلة عبر: grep -d skip الذي يتخطى بصمت مثل "أسماء الدليل" المدخلات.

مع gnu grep ، يمكنك استخدام -H بدلا من /dev/null. كمسألة جانبية طفيفة: \+ يمكن أن يكون أسرع بكثير من \;على سبيل المثال لمليون ملف من سطر واحد ، باستخدام \; استغرق 4m20sباستخدام \+ استغرق الأمر فقط 1.2s.

تستخدم الطريقة التالية xargs بدلا من -exec، ويفترض عدم وجود خطوط جديدة \n في أي ملف من ملفك أسماء. كما هو مستخدم هنا ، xargs هو نفس الشيء مثل العثور على \+.

xargs يمكن تمرير أسماء الملفات التي تحتوي على مسافات متتالية عن طريق تغيير محدد الإدخال إلى '\n' مع ال -d اختيار.

هذا يستبعد الدلائل التي أسماء يحتوي  .svn و greps فقط الملفات التي لا تنتهي .html.

find . \( -name '*.svn*' -prune  -o ! -name '*.html' \) |
   xargs -d '\n' grep -Hd skip 'SearchString'

7
2018-03-06 03:29



شكرا لافراكم \+ متغير من الإجراء -exec. الصيحة لقضايا جانبية طفيفة! - Christian Long
بالطبع ، منذ ذلك الحين + ليست شخصية خاصة بالصدفة ، فأنت لست بحاجة إلى الكتابة \ قبل ذلك. - Scott