2009-05-11 18 views
8

में ट्रिकी ब्रेस विस्तार जब एक POSIX खोल का उपयोग करते हुए,खोल

touch {quick,man,strong}ly 

निम्नलिखित

touch quickly manly strongly 

कौन सा फ़ाइलों quickly, manly, और strongly स्पर्श करेगा करने के लिए फैलता है, लेकिन यह गतिशील रूप से संभव है विस्तार बनाएँ? उदाहरण के लिए, निम्नलिखित दिखाता है मुझे क्या करना चाहते हैं, लेकिन विस्तार के आदेश की वजह से काम नहीं करता है:

TEST=quick,man,strong #possibly output from a program 
echo {$TEST}ly 

वहाँ किसी भी तरह से इस लक्ष्य को हासिल करने के लिए है? यदि आवश्यकता हो तो मुझे बैश में खुद को बांधने की कोई बात नहीं है। मैं लूप से बचना भी चाहूंगा। विस्तार किसी भी मनमाना कार्यक्रम के लिए पूर्ण तर्क के रूप में दिया जाना चाहिए (यानी कार्यक्रम को प्रत्येक फ़ाइल के लिए एक बार नहीं कहा जा सकता है, इसे केवल सभी फ़ाइलों के लिए एक बार बुलाया जा सकता है)। मुझे xargs के बारे में पता है, लेकिन मुझे आशा है कि यह किसी भी तरह से खोल से किया जा सकता है।

+0

ब्रेस विस्तार में निर्धारित नहीं है POSIX खोल: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06 – pabouk

+2

@pabouk: यह सही है, अब मुझे पता है कि ब्रेस विस्तार POSIX नहीं है, लेकिन 7 साल पहले (जब मैंने पूछा यह सवाल) मुझे यह नहीं पता था :) – dreamlax

उत्तर

17

... वहाँ इतना eval उपयोग करने के साथ गलत है। आप जो पूछ रहे हैं वह केवल eval, के साथ संभव है आप को बश-बग-सेंट्रल का उपयोग किए बिना आसानी से संभव है।

सरणी का प्रयोग करें! जब भी आप में एक डेटाप्रकार कई आइटम रखने की जरूरत है, तो आप की जरूरत है (या, चाहिए उपयोग) एक सरणी।

TEST=(quick man strong) 
touch "${TEST[@]/%/ly}" 

यही तुम क्या चाहते हजार कीड़े और सुरक्षा के मुद्दों की शुरुआत की और अन्य सुझावों यहाँ में छुपा के बिना नहीं करता है।

जिस तरह से यह काम करता है:

  • "${foo[@]}": सरणी उसके तत्वों, ठीक से उद्धृत से प्रत्येक का विस्तार करके foo नामित विस्तृत करता है। उद्धरण मत भूलना!
  • ${foo/a/b}: यह पैरामीटर विस्तार का एक प्रकार है जो पहले a को foo के b द्वारा विस्तारित करता है। इस प्रकार के विस्तार में आप का उपयोग को विस्तारित मान के अंत में इंगित करने के लिए कर सकते हैं, जैसे नियमित अभिव्यक्तियों में $ की तरह।
  • सभी को एक साथ रखो और "$ {foo [@] /%/ly}" foo के प्रत्येक तत्व का विस्तार करेगा, इसे एक अलग तर्क के रूप में सही ढंग से उद्धृत करें, और प्रत्येक तत्व के अंत को ly द्वारा प्रतिस्थापित करें।
+0

विस्तार के कई स्तरों के लिए इसके लिए कोई सुझाव? उदाहरण के लिए, 'echo {a, b}/{c, d}/{e, f} ''/c/ea/c/fa/d/ea/d/fb/c/eb/c/fb देता है/डी/ईबी/डी/एफ'; क्या मैं लूप लिखने के बिना, सरणी के साथ प्राप्त कर सकता हूं? – sdaau

+0

@sdaau आप एक सरणी में ब्रेस विस्तार असाइन कर सकते हैं। फाइल = ({ए, बी}/{सी, डी}/{ई, एफ}); "$ {files [@]} स्पर्श करें" – lhunath

+0

नोटिस आप आइटम को उपसर्ग करने के लिए '%' के बजाय '#' का उपयोग कर सकते हैं: '$ {टेस्ट [@]/#/ly} 'lyquick lyman lystrong' देता है – Jezz

3

बैश में, आप यह कर सकते हैं: अंतिम पंक्ति पर टिप्पणी की है, लेकिन निर्दिष्ट फ़ाइलों स्पर्श करेगा

#!/bin/bash 
TEST=quick,man,strong 
eval echo $(echo {$TEST}ly) 
#eval touch $(echo {$TEST}ly) 

है।

+3

बस इतना ही पता है कि उस समाधान के साथ बहुत से मुद्दे हैं, जो सिर्फ छिपाते हैं क्योंकि आप अपने टेस्ट पैरामीटर में केवल अक्षरों और कॉमा का उपयोग कर रहे हैं। बैश में विशेष अर्थ रखने वाला कोई भी चरित्र इसे खराब कर देगा, खासकर इसलिए क्योंकि आप कुछ भी उद्धृत करने में पूरी तरह विफल रहे हैं। मुझे एहसास है कि यह दिए गए आंकड़ों के साथ एक डेमो है लेकिन वास्तविक समाधान में इस समाधान का उपयोग करना एक पाप है। – lhunath

+0

@paxdiablo: आप 'eval echo $ (echo {$ test} ly) के बजाय' eval echo {$ TEST} ly' का उपयोग कर सकते हैं। AFAIK अतिरिक्त गूंज कुछ भी नहीं जोड़ता है। – iconoclast

+0

@ लुननाथ: आप 'eval' को तुच्छ मानते हैं। क्या इसमें कुछ विशेष रूप से गलत है जो किसी समस्या का कारण बनता है, या आप आसानी से बुराई होने के लिए 'eval' के साथ कुछ भी मानते हैं? – iconoclast

0

ऊपर जवाब से प्रेरणा ले रहा है:

$ TEST=quick,man,strong 
$ touch $(eval echo {$TEST}ly) 
0

Zsh आसानी से ऐसा कर सकते हैं:

TEST=quick,man,strong 
print ${(s:,:)^TEST}ly 

चर सामग्री के लिए अल्पविराम में splitted है, तो प्रत्येक तत्व ब्रेसिज़ के आसपास स्ट्रिंग के लिए वितरित किया जाता है:

quickly manly strongly