سؤال

أنا لا أفهم ذلك تماما الواردة من man find, ، هل يمكن لأي شخص أن يعطيني بعض الأمثلة والتفسيرات؟ هل يمكنني الجمع بين التعبير المنتظم فيه؟


السؤال الأكثر تفصيلا هو مثل هذا:

اكتب نص شل، changeall, ، والتي لديها واجهة مثل changeall [-r|-R] "string1" "string2". وبعد سوف تجد جميع الملفات مع لاحقة .h, .C, .cc, ، أو .cpp وتغيير جميع تكرارات string1 ل string2. -r هو خيار للبقاء في دير الحالي فقط أو بما في ذلك SUBDIR.

ملاحظة:

  1. للحالة غير العودية، ls غير مسموح به، يمكننا فقط استخدام find و sed.
  2. حاولت find -depth لكنه لم يكن مدعوما. لهذا السبب كنت أتساءل إذا -prune يمكن أن تساعد، لكنها لم تفهم المثال من man find.

Edit2: كنت أفعل المهمة، لم أسأل السؤال في تفاصيل كبيرة لأنني أرغب في الانتهاء من ذلك بنفسي. منذ أن فعلت ذلك بالفعل وتسليمها، الآن يمكنني ذكر السؤال بأكمله. أيضا، تمكنت من إنهاء المهمة دون استخدام -prune, ولكن أود أن أتعلم ذلك على أي حال.

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

المحلول

الشيء الذي كنت قد وجدت مربكا عنه -prune هو أنه عمل (مثل -print)، وليس اختبار (مثل -name). يغير قائمة "To Do"، ولكن دائما إرجاع صحيح.

النمط العام لاستخدام -prune هذا هو:

find [path] [conditions to prune] -prune -o \
            [your usual conditions] [actions to perform]

أنت دائما تريد دائما -o (منطقي أو) مباشرة بعد -prune, ، لأن هذا الجزء الأول من الاختبار (حتى بما في ذلك -prune) سيعود خاطئة بالنسبة للأشياء التي تريدها فعلا (أي: الأشياء التي لا تريد أن تقلص).

إليك مثال:

find . -name .snapshot -prune -o -name '*.foo' -print

سيجد هذا ملفات "* .Foo" التي ليست تحت أدلة ".snapshot". في هذا المثال، -name .snapshot يشكل [conditions to prune], ، و -name '*.foo' -print يكون [your usual conditions] و [actions to perform].

ملاحظات هامة:

  1. إذا كان كل ما تريد القيام به هو طباعة النتائج التي قد تستخدمها لإخراج -print عمل. أنت عموما لا تريد أن تفعل ذلك عند استخدام -prune.

    السلوك الافتراضي للعثور هو "و" بأكمله التعبير مع -print العمل إذا لم تكن هناك إجراءات أخرى غير -prune (من المفارقات) في النهاية. وهذا يعني أن كتابة هذا:

    find . -name .snapshot -prune -o -name '*.foo'              # DON'T DO THIS
    

    أي ما يعادل كتابة هذا:

    find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
    

    مما يعني أنه سوف يطبع أيضا اسم الدليل الذي تشوهات، والذي عادة ليس ما تريد. بدلا من ذلك من الأفضل تحديد ذلك بشكل صريح -print العمل إذا كان هذا ما تريد:

    find . -name .snapshot -prune -o -name '*.foo' -print       # DO THIS
    
  2. إذا حدث "حالتك المعتادة" لتتناسب مع الملفات التي تطابق أيضا شرط PRUNE الخاص بك، فإن تلك الملفات سوف ليس أن تدرج في الإخراج. الطريق لإصلاح هذا هو إضافة -type d المسند لحالة القطع الخاصة بك.

    على سبيل المثال، لنفترض أننا أردنا تقليل أي دليل بدأ .git (من المسلم به هذا مفهومة إلى حد ما - عادة ما تحتاج فقط إلى إزالة الشيء المسمى بالضبط .git)، ولكن بخلاف ذلك أراد أن يرى جميع الملفات، بما في ذلك الملفات مثل .gitignore. وبعد قد تحاول هذا:

    find . -name '.git*' -prune -o -type f -print               # DON'T DO THIS
    

    هذا سيكون ليس تتضمن .gitignore في الإخراج. إليك النسخة الثابتة:

    find . -type d -name '.git*' -prune -o -type f -print       # DO THIS
    

نصيحة إضافية: إذا كنت تستخدم إصدار جنو من find, ، صفحة Texinfo ل find لديه شرح أكثر تفصيلا من manpage (كما هو صحيح بالنسبة لمعظم مرافق جنو).

نصائح أخرى

حذار أن -برون لا يمنع تنازلي أي دليل كما قال البعض. يمنع تنازلي في الدلائل التي تتطابق مع الاختبار المطبق عليها. ربما سيساعد بعض الأمثلة (انظر أسفل مثال Regex). آسف لهذا كونها طويلة جدا.

$ find . -printf "%y %p\n"    # print the file type the first time FYI
d .
f ./test
d ./dir1
d ./dir1/test
f ./dir1/test/file
f ./dir1/test/test
d ./dir1/scripts
f ./dir1/scripts/myscript.pl
f ./dir1/scripts/myscript.sh
f ./dir1/scripts/myscript.py
d ./dir2
d ./dir2/test
f ./dir2/test/file
f ./dir2/test/myscript.pl
f ./dir2/test/myscript.sh

$ find . -name test
./test
./dir1/test
./dir1/test/test
./dir2/test

$ find . -prune
.

$ find . -name test -prune
./test
./dir1/test
./dir2/test

$ find . -name test -prune -o -print
.
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

$ find . -regex ".*/my.*p.$"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test/myscript.pl

$ find . -name test -prune -regex ".*/my.*p.$"
(no results)

$ find . -name test -prune -o -regex ".*/my.*p.$"
./test
./dir1/test
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test

$ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py

$ find . -not -regex ".*test.*"                   .
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

عادة الطريقة الأصلية التي نقوم بها الأشياء في لينكس والطريقة التي نعتقد أنها من اليسار إلى اليمين.
لذلك سوف تذهب واكتب ما تبحث عنه أولا:

find / -name "*.php"

ثم ربما تضغط على المدخل وأدرك أنك تحصل على العديد من الملفات من الدلائل التي ترغب في ذلك. دعونا نستبعد / وسائل الإعلام لتجنب البحث عن محركات الأقراص المثبتة.
يجب عليك الآن إلحاق ما يلي فقط بالأمر السابق:

-print -o -path '/media' -prune

لذلك الأمر النهائي هو:

find / -name "*.php" -print -o -path '/media' -prune

............... | <--- تشمل ---> | .................... | <- -------- باستثناء ---------> |

أعتقد أن هذا الهيكل أسهل بكثير ويرتبط بالنهج الصحيح

إضافة إلى النصيحة المقدمة في إجابات أخرى (ليس لدي ممثل لإنشاء ردود) ...

عند الجمع -prune مع تعبيرات أخرى، هناك اختلاف دقيق في السلوك اعتمادا على التعبيرات الأخرى المستخدمة.

ستجد مثال Laurence Gonsalves ملفات "* .Foo" التي ليست تحت أدلة ".snapshot": -

find . -name .snapshot -prune -o -name '*.foo' -print

ومع ذلك، هذه الإرادة القصيرة مختلفة قليلا، ربما عن غير قصد، قائمة أيضا .snapshot الدليل (وأي أدلة متداخلة .snapshot): -

find . -name .snapshot -prune -o -name '*.foo'

السبب هو (وفقا ل WanPage على نظامي): -

إذا كان التعبير المحدد لا يحتوي على أي من عمليات الانتخابات التمهيدية -EXEC أو -LS أو -OK أو -Print، يتم استبدال التعبير المعطى بفعالية ب:

(adite_expression) -

وهذا هو، المثال الثاني هو ما يعادل دخول ما يلي، وبالتالي تعديل تجميع المصطلحات: -

find . \( -name .snapshot -prune -o -name '*.foo' \) -print

وقد شودا هذا على الأقل على Solaris 5.10. بعد أن استخدمت نكهات مختلفة من * Nix لمدة 10 سنوات تقريبا، فقد بحثت مؤخرا عن سبب يحدث هذا.

Prunce هي عدم الانصهار في أي مفتاح دليل.

من صفحة الرجل

إذا لم يعط، صحيح؛ إذا كان الملف دليلا، فلا تنحدر فيه. إذا تم إعطاء -depth، خطأ؛ بدون تأثير.

في الأساس لن نغفز إلى أي دلائل فرعية.

خذ هذا المثال:

لديك الدلائل التالية

  • / الصفحة الرئيسية / Test2
  • / الرئيسية / test2 / test2

اذا ركضت find -name test2:

سيعيد كل من الدلاريخ

اذا ركضت find -name test2 -prune:

سيعود فقط / الصفحة الرئيسية / Test2 لأنها لن تنحدر إلى / الصفحة الرئيسية / Test2 للعثور على / الصفحة الرئيسية / Test2 / Test2

أنا لا خبير في هذا (وهذه الصفحة كانت مفيدة للغاية مع http://mywiki.wooledg.org/usingfind.)

فقط لاحظت -path هو للمسار الذي تطابق تماما السلسلة / المسار الذي يأتي بعد find (. في أمثلة الرسائل) أينما -name يطابق جميع الأسماء الأساسية.

find . -path ./.git  -prune -o -name file  -print

كتل دليل .git في الدليل الحالي الخاص بك ( كما الاكتشاف الخاص بك في . )

find . -name .git  -prune -o -name file  -print

كتل جميع الدلائل الفرعية .git بشكل متكرر.

لاحظ ال ./ هو مهم للغاية! -path يجب أن تطابق مسار الراسية . أو كل ما يأتي بعد العثور عليها إذا حصلت على التطابقات معها (من الجانب الآخر من أو "-o") ربما لا يوجد متذكير! كنت غير مدرك للغاية لهذا ووضعني باستخدام -Path عندما يكون رائعا عندما لا ترغب في تقليم جميع الدليل الفرعي بنفس الاسم البصري: D

إظهار كل شيء بما في ذلك Dir نفسه ولكن ليس محتوياتها المملية الطويلة:

find . -print -name dir -prune

إذا قرأت كل الإجابات الجيدة هنا فهمي الآن هو أن كل ما يلي إرجاع نفس النتائج:

find . -path ./dir1\*  -prune -o -print

find . -path ./dir1  -prune -o -print

find . -path ./dir1\*  -o -print
#look no prune at all!

ولكن آخر واحد سوف يستغرق وقتا أطول بكثير لأنه لا يزال يبحث عن كل شيء في DIR1. أعتقد أن السؤال الحقيقي هو كيفية -or النتائج غير المرغوب فيها دون البحث في الواقع.

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

http://www.gnu.org/software/findutils/manual/html_mono/find.html."لكن هذا لا يرجع إلى تأثير الإجراء" -prune "(الذي يمنع فقط النزول فقط، فإنه لا يتأكد من أننا نتجاهل هذا البند). بدلا من ذلك، هذا التأثير يرجع إلى استخدام" -o ". نظرا لأن الجانب الأيسر من حالة "أو" نجحت في ./src/emacs، ليس من الضروري تقييم الجانب الأيمن ("-print") على الإطلاق لهذا الملف المحدد. "

find يبني قائمة الملفات. ينطبق المسند الذي توفره لكل واحد وإرجاع تلك التي تمر.

هذه الفكرة مفادها أن -prune يعني الاستبعاد من النتائج كان مربكا حقا بالنسبة لي. يمكنك استبعاد ملف دون تقليم:

find -name 'bad_guy' -o -name 'good_guy' -print  // good_guy

الجميع -prune هل يغير سلوك البحث. إذا كانت المباراة الحالية دليل، فتقول "يا find, ، هذا الملف الذي تطابقك فقط، لا تنحدر فيه ". وبعد فقط يزيل هذه الشجرة (ولكن ليس الملف نفسه) من قائمة الملفات للبحث.

يجب اسمه -dont-descend.

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