एक उपनाम शेल में आंतरिक होता है जहां इसे परिभाषित किया जाता है। यह अन्य प्रक्रियाओं के लिए दृश्यमान नहीं है। वही शेल फंक्शंस के लिए जाता है। xargs
एक अलग अनुप्रयोग है, जो एक शेल नहीं है, इसलिए इसमें उपनाम या फ़ंक्शन की अवधारणा नहीं है।
आप xargs को grep
सीधे इन्वॉल्व करने के बजाय शेल खोल सकते हैं । हालाँकि, केवल शेल खोलना ही पर्याप्त नहीं है, आपको उस शेल में भी अन्य को परिभाषित करना होगा। यदि उपनाम आपके में परिभाषित किया गया है .bashrc
, तो आप उस फ़ाइल को स्रोत कर सकते हैं; हालाँकि यह आपके .bashrc
अन्य कार्यों को काम नहीं कर सकता है जो एक गैर-इंटरैक्टिव शेल में कोई मतलब नहीं रखते हैं।
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E regex_here "$@"' _
Regexp टाइप करते समय नेस्टेड उद्धरण की जटिलताओं से सावधान रहें। आप शेल के एक पैरामीटर के रूप में regexp पास करके अपने जीवन को सरल बना सकते हैं।
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E "$0" "$@"' regex_here
आप स्पष्ट रूप से उपनाम खोज कर सकते हैं। फिर xargs
देखेंगे grep -n --color=always
।
find . -name '*.py' | xargs "${BASH_ALIASES[grep]}" regex_here
Zsh में:
find . -name '*.py' | xargs $aliases[grep] regex_here
वैसे, ध्यान दें कि find … | xargs …
रिक्त स्थान (दूसरों के बीच) वाले फ़ाइलनाम पर टूट जाता है । आप इसे नल-सीमांकित रिकॉर्ड में बदलकर ठीक कर सकते हैं:
find . -name '*.py' -print0 | xargs -0 "${BASH_ALIASES[grep]}" regex_here
या उपयोग करके -exec
:
find . -name '*.py' -exec "${BASH_ALIASES[grep]}" regex_here {} +
कॉल करने के बजाय find
, आप पूरी तरह से शेल के अंदर सब कुछ कर सकते हैं। ग्लोब पैटर्न **/
ट्रैवर्सेस निर्देशिकाओं को पुनरावर्ती बनाता है। बैश में, आपको shopt -s globstar
पहले इस ग्लोब पैटर्न को सक्षम करने के लिए दौड़ना होगा।
grep regex_here **/*.py
इसकी कुछ सीमाएँ हैं:
- यदि बहुत सारी फाइलें मेल खाती हैं (या यदि उनके पास लंबे रास्ते हैं), तो कमांड विफल हो सकती है क्योंकि यह अधिकतम कमांड लाइन की लंबाई से अधिक है।
- Bash b4.2 में (लेकिन अधिक हाल के संस्करणों में नहीं, न ही ksh या zsh में),
**/
निर्देशिकाओं के प्रतीकात्मक लिंक में पुनरावृत्ति करता है।
एक अन्य दृष्टिकोण प्रक्रिया प्रतिस्थापन का उपयोग करना है, जैसा कि मारियसमैटुटिया द्वारा सुझाया गया है ।
grep regex_here <(find . -name '*.py')
यह तब **/
लागू होता है जब यह लागू नहीं होता है: जटिल find
अभिव्यक्तियों के लिए, या जब आप सांकेतिक लिंक के तहत पुनरावृत्ति नहीं करना चाहते हैं, तो ≤4.2 को रोकें। ध्यान दें कि यह रिक्त स्थान वाले फ़ाइल नामों पर टूटता है; ग्लोबिंग को सेट IFS
और अक्षम करने के लिए एक वर्कअराउंड है , लेकिन यह थोड़ा जटिल होने लगा है:
(IFS=$'\n'; set -f; grep regex_here <(find . -name '*.py') )