ऐसा लगता है कि इस पृष्ठ पर सभी मौजूदा उत्तर गलत हैं, जिनमें से एक को सही के रूप में चिह्नित किया गया है। यह इस तथ्य से उपजा है कि प्रश्न अस्पष्ट शब्द है।
सारांश: यदि आप दिए गए इनपुट के प्रत्येक लाइन के लिए "बिल्कुल एक बार" कमांड को निष्पादित करना चाहते हैं , तो पूरी लाइन (न्यूलाइन के बिना) को कमांड में एक ही तर्क के रूप में पास करना है, तो यह करने के लिए सबसे अच्छा यूनिक्स-संगत तरीका है:
... | tr '\n' '\0' | xargs -0 -n1 ...
जीएनयू xargs
में उपयोगी एक्सटेंशन हो सकते हैं या नहीं हो सकते हैं जो आपको दूर करने की अनुमति देते हैं tr
, लेकिन वे ओएस एक्स और अन्य यूनिक्स प्रणालियों पर उपलब्ध नहीं हैं।
अब लंबे स्पष्टीकरण के लिए ...
Xargs का उपयोग करते समय दो मुद्दों को ध्यान में रखना है:
- यह इनपुट को "तर्कों" में कैसे विभाजित करता है; तथा
- एक बार में बाल आदेश पारित करने के लिए कितने तर्क हैं।
Xargs के व्यवहार का परीक्षण करने के लिए, हमें एक उपयोगिता की आवश्यकता होती है जो यह दर्शाती है कि इसे कितनी बार निष्पादित किया जा रहा है और कितने तर्कों के साथ। मुझे नहीं पता कि ऐसा करने के लिए कोई मानक उपयोगिता है या नहीं, लेकिन हम इसे आसानी से बैश में कोड कर सकते हैं:
#!/bin/bash
echo -n "-> "; for a in "$@"; do echo -n "\"$a\" "; done; echo
मान लें कि आप इसे show
अपनी वर्तमान निर्देशिका के रूप में सहेजते हैं और इसे निष्पादन योग्य बनाते हैं, यहां बताया गया है कि यह कैसे काम करता है:
$ ./show one two 'three and four'
-> "one" "two" "three and four"
अब, यदि मूल प्रश्न वास्तव में बिंदु 2 के ऊपर है। ऊपर (जैसा कि मुझे लगता है कि यह कुछ ही समय में पढ़ने के बाद है), और इसे इस तरह से पढ़ना है (बोल्ड में परिवर्तन):
मैं दिए गए इनपुट के प्रत्येक तर्क के लिए xargs को कमांड को एक बार कैसे निष्पादित कर सकता हूं ? इसका डिफ़ॉल्ट व्यवहार इनपुट को तर्कों में तब्दील करना और प्रत्येक उदाहरण के लिए कई तर्कों को पारित करते हुए कमांड को यथासंभव कम से कम निष्पादित करना है ।
तो जवाब है -n 1
।
आइए xargs के डिफ़ॉल्ट व्यवहार की तुलना करें, जो व्हॉट्सएप के चारों ओर इनपुट को विभाजित करता है और कमांड को जितनी बार संभव हो सके कॉल करता है:
$ echo one two 'three and four' | xargs ./show
-> "one" "two" "three" "and" "four"
और इसके साथ व्यवहार -n 1
:
$ echo one two 'three and four' | xargs -n 1 ./show
-> "one"
-> "two"
-> "three"
-> "and"
-> "four"
यदि, दूसरी ओर, मूल प्रश्न बिंदु 1 था। इनपुट विभाजन और इसे इस तरह से पढ़ा जाना था (यहां आने वाले कई लोगों को लगता है कि मामला है, या दो मुद्दों को भ्रमित कर रहे हैं)
मैं दिए गए इनपुट की प्रत्येक पंक्ति के लिए xargs को कमांड को बिल्कुल एक तर्क से कैसे निष्पादित कर सकता हूं ? इसका डिफ़ॉल्ट व्यवहार व्हाट्सएप के आसपास की लाइनों को चोक करना है ।
तब उत्तर अधिक सूक्ष्म होता है।
किसी को लगता है कि -L 1
मदद की जा सकती है, लेकिन यह पता चला है कि यह तर्क पार्सिंग को नहीं बदलता है। यह प्रत्येक इनपुट लाइन के लिए केवल एक बार कमांड निष्पादित करता है, उस इनपुट लाइन पर जितने भी तर्क थे उतने ही हैं:
$ echo $'one\ntwo\nthree and four' | xargs -L 1 ./show
-> "one"
-> "two"
-> "three" "and" "four"
इतना ही नहीं, लेकिन अगर एक लाइन व्हॉट्सएप के साथ समाप्त होती है, तो इसे अगले में जोड़ा जाता है:
$ echo $'one \ntwo\nthree and four' | xargs -L 1 ./show
-> "one" "two"
-> "three" "and" "four"
स्पष्ट रूप से, -L
xargs द्वारा इनपुट को तर्कों में विभाजित करने के तरीके को बदलने के बारे में नहीं है।
क्रॉस-प्लेटफ़ॉर्म फ़ैशन (GNU एक्सटेंशन को छोड़कर) में ऐसा करने वाला एकमात्र तर्क है -0
, जो NUL बाइट्स के चारों ओर इनपुट को विभाजित करता है।
फिर, NUL की मदद से newlines का अनुवाद करने की बात है tr
:
$ echo $'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show
-> "one " "two" "three and four"
अब तर्क पार्सिंग सब ठीक लग रहा है, जिसमें पीछे वाला व्हाट्सएप भी शामिल है।
अंत में, यदि आप इस तकनीक के साथ गठबंधन करते हैं, तो आपको -n 1
इनपुट लाइन प्रति एक कमांड निष्पादन मिलता है, आपके पास जो भी इनपुट है, जो मूल प्रश्न को देखने का एक और तरीका हो सकता है (संभवतः सबसे सहज, शीर्षक दिया गया):
$ echo $'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 ./show
-> "one "
-> "two"
-> "three and four"
find /path -type f -delete
और भी अधिक कुशल होगा :)