GNU टूल्स के साथ:
find . -type f -exec grep -lZ FIND {} + | xargs -r0 grep -l ME
आप मानक रूप से कर सकते हैं:
find . -type f -exec grep -q FIND {} \; -exec grep -l ME {} \;
लेकिन वह प्रति फ़ाइल दो greps चलाएगा। कई grep
नामों को चलाने से बचने के लिए और अभी भी पोर्टेबल होने के बावजूद फ़ाइल नामों में किसी भी चरित्र की अनुमति दें, आप कर सकते हैं:
convert_to_xargs() {
sed "s/[[:blank:]\"\']/\\\\&/g" | awk '
{
if (NR > 1) {
printf "%s", line
if (!index($0, "//")) printf "\\"
print ""
}
line = $0
}'
END { print line }'
}
find .//. -type f |
convert_to_xargs |
xargs grep -l FIND |
convert_to_xargs |
xargs grep -l ME
find
ज़ारगेज़ के लिए उपयुक्त प्रारूप के आउटपुट को बदलने के लिए किया जा रहा विचार (जो एक रिक्त (SPC / TAB / NL, और आपके स्थान से अन्य रिक्तियाँ कुछ कार्यान्वयन के साथ की अपेक्षा करता है xargs
) शब्दों की सूची को अलग कर देता है जहाँ एकल, दोहरे उद्धरण और बैकस्लैश हो सकते हैं बचने के रिक्त स्थान और एक दूसरे)।
आम तौर पर आप इसके आउटपुट को पोस्ट-प्रोसेस नहीं कर सकते find -print
, क्योंकि यह फ़ाइल नामों को एक नई लाइन वर्ण के साथ अलग करता है और फ़ाइल नामों में पाए जाने वाले नए अक्षरों से बच नहीं सकता है। उदाहरण के लिए अगर हम देखें:
./a
./b
हमें यह जानने का कोई तरीका नहीं है कि क्या यह b
एक निर्देशिका नामक एक फाइल है जिसे a<NL>.
या तो यह दो फाइलें हैं a
और b
।
उपयोग करके .//.
, क्योंकि //
आउटपुट के रूप में फ़ाइल पथ में अन्यथा दिखाई नहीं दे सकता find
(क्योंकि खाली नाम के साथ निर्देशिका जैसी कोई चीज़ /
नहीं है और फ़ाइल नाम में अनुमति नहीं है), हम जानते हैं कि यदि हम एक पंक्ति देखते हैं जिसमें शामिल है //
, तो वह है एक नए फ़ाइल नाम की पहली पंक्ति। इसलिए हम awk
सभी नए अक्षरों से बचने के लिए उस कमांड का उपयोग कर सकते हैं, लेकिन उन लाइनों से पहले।
यदि हम ऊपर का उदाहरण लेते हैं, find
तो पहले मामले में आउटपुट (एक फ़ाइल):
.//a
./b
जो जागता है:
.//a\
./b
ताकि xargs
इसे एक तर्क के रूप में देखें। और दूसरे मामले में (दो फाइलें):
.//a
.//b
जो awk
जैसा है, वैसा ही छोड़ देगा, इसलिए xargs
दो तर्क देखता है।