xargs - प्रत्येक तर्क को एक पैरामीटर के साथ जोड़ते हैं


जवाबों:


13

इसे करने का एक तरीका:

echo "a b c" | xargs printf -- '-f %s\n' | xargs mycommand

यह मानता है a, bऔर cइसमें रिक्तियां, newlines, उद्धरण या बैकस्लैश शामिल नहीं हैं। :)

जीएनयू के साथ findutilआप सामान्य मामले को संभाल सकते हैं, लेकिन यह थोड़ा अधिक जटिल है:

echo -n "a|b|c" | tr \| \\0 | xargs -0 printf -- '-f\0%s\0' | xargs -0 mycommand

आप बदल सकते हैं |, कुछ अन्य चरित्र के साथ विभाजक कि में प्रकट नहीं होता a, bया c

संपादित करें: के रूप में @MichaelMol नोट, तर्कों की एक बहुत ही लंबी सूची के साथ वहाँ बहस करने के लिए पारित किया जा सकता है कि की अधिकतम लंबाई बह निकला का खतरा रहता है mycommand। जब ऐसा होता है, तो अंतिम xargsसूची को विभाजित कर देगा और उसकी एक और प्रतिलिपि चलाएगा mycommand, और इसके अनधिकृत रूप से छोड़ने का जोखिम है -f। यदि आप उस स्थिति के बारे में चिंता करते हैं, तो आप xargs -0इस तरह से पिछले कुछ को बदल सकते हैं :

... | xargs -x -0 mycommand

यह समस्या को हल नहीं करेगा, लेकिन mycommandजब तर्कों की सूची बहुत लंबी हो जाएगी तो यह चल रहा है ।


1
आप अपने युग्मित पैरामीटर से अलग ARG_MAXहोने और होने का एक बहुत बदसूरत जोखिम चलाते हैं -f
माइकल मोल

@MichaelMol यह एक अच्छा बिंदु है, लेकिन मुझे नहीं लगता कि इस बारे में अधिक जानकारी के बिना उस स्थिति को संभालने का कोई सार्थक तरीका है mycommand। आप हमेशा -xअंतिम में जोड़ सकते हैं xargs
सातु कटुरा

मुझे लगता है कि उचित समाधान संभवत: उपयोग करने के लिए नहीं है xargs, और बस उपयोग findकिया जा सकता है। यह समाधान खतरनाक है; आपको कम से कम अपने जवाब में विफलता के मामले की चेतावनी देनी चाहिए।
माइकल मोल

@MichaelMol मैं वास्तव में यह नहीं देखता कि findएक बेहतर सामान्य समाधान कैसे होगा, खासकर जब शुरुआती तर्क फ़ाइल नाम नहीं हैं। :)
शनि कत्सुरा

हमें नहीं पता कि शुरुआती तर्क क्या हैं; हम केवल दिए गए उदाहरण को देखते हैं, न कि उस परिदृश्य को जिसने प्रश्न को प्रेरित किया। अंतर्ज्ञान से पता चलता है कि एक तर्क नाम के -fसाथ, और उदाहरण के lsलिए चित्रण के लिए उपयोग किए जाने वाले उपकरण के साथ , @ not-a-user फ़ाइलनाम के साथ काम कर रहा है। और दिया findगया -execतर्क प्रदान करता है, जो आपको कमांड-लाइन बनाने की अनुमति देता है , यह ठीक है। (जब तक mycommandइसे एक से अधिक बार निष्पादित करने की अनुमति है। यदि यह नहीं है, तो हमें xargsयहां उपयोग के साथ एक और समस्या है ...)
माइकल मोल

5

इसे संबोधित करने का एक बेहतर तरीका (IMO) होगा:

  • में zsh:

    l=(a b c)
    mycommand -f$^l
    

    या सरणी ज़िपिंग का उपयोग करना ताकि तर्क विकल्प से जुड़ा न हो:

    l=(a b c) o=(-f)
    mycommand "${o:^^l}"
    

    इस तरह, यह अभी भी काम करता है यदि lसरणी में रिक्त स्थान या तत्व होते हैं जिनमें रिक्त स्थान या किसी अन्य समस्याग्रस्त चरित्र होते हैं xargs। उदाहरण:

    $ l=(a '' '"' 'x y' c) o=(-f)
    $ printf '<%s>\n' "${o:^^l}"
    <-f>
    <a>
    <-f>
    <>
    <-f>
    <">
    <-f>
    <x y>
    <-f>
    <c>
    
  • में rc:

    l=(a b c)
    mycommand -f$l
    
  • में fish:

    set l a b c
    mycommand -f$l
    

(AFAIK, rcऔर fishकोई सरणी ज़िपिंग नहीं है)

पुराने शैली के बॉर्न-जैसे गोले की तरह bash, आप हमेशा (अभी भी $@सरणी के तत्वों में किसी भी वर्ण को अनुमति दे सकते हैं ):

set -- a b c
for i do set -- "$@" -f "$i"; shift; done
mycommand "$@"

1
बैश में इसे करने का एक और तरीका नामित सरणी चर के साथ है। for i; do args+=('-f' "$i");done; mycommand "${args[@]}"। IDK यदि यह तेज़ है, लेकिन किसी सरणी में 2 तत्वों को जोड़ना ऐसा लगता है जैसे कि यह O (n) होना चाहिए, जबकि आपका setलूप संभवत: हर बार संचित arg सूची (O (n ^ 2)) को कॉपी करता है।
पीटर कॉर्ड्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.