2012-09-07 50 views
5

मैं मेकफ़ाइल लिख रहा हूं और मैं फ़िल्टर फ़ंक्शन सीमा पर फंस गया हूं। वास्तव में, फ़िल्टर केवल एक वाइल्डकार्ड लेता है।मेकफ़ाइल: एकाधिक वाइल्डकार्ड पर फ़िल्टर करने के बराबर कैसे लागू करें

मैं क्या करना चाहता हूं: मेरे पास एक फाइल है, कुछ regexp blabla से मेल खाते हैं, कुछ नहीं। लेकिन इसके लिए मुझे 2 वाइल्डकार्ड चाहिए, इस प्रकार मैं फिल्टर फ़ंक्शन का उपयोग नहीं कर सकता।

मैं अपनी मूल सूची को 2 सूचियों में विभाजित करना चाहता हूं, जिसमें ब्लैब्ला स्ट्रिंग (फ़िल्टर समतुल्य) वाले सभी तत्व शामिल हैं और दूसरा जिसमें मिलान करने वाला कोई नहीं है (फ़िल्टर-आउट समतुल्य)।

आपकी सहायता के लिए धन्यवाद।

+1

आप जीएनयू बनाने या किसी अन्य संस्करण का उपयोग कर रहे कर सकते हैं? और अपना वर्तमान कोड दिखाएं, यह स्पष्ट नहीं है कि समस्या क्या है। – Gilles

+1

कृपया फाइलों, फ़िल्टर अभिव्यक्ति और वांछित परिणाम की एक उदाहरण सूची प्रदान करें। जिस तरह से आप इसका वर्णन करते हैं, यह मुझे स्पष्ट नहीं है कि '$ (फ़िल्टर ...)' और '$ (फ़िल्टर-आउट ...) 'फ़ंक्शन आपके लिए पर्याप्त क्यों नहीं हैं। –

+0

आपके उत्तर के लिए धन्यवाद। मैं gnu बनाने का उपयोग कर रहा हूँ। मेरे पास दिखाने के लिए कोड नहीं है क्योंकि मैं यह नहीं समझ सकता कि इसे कैसे लिखना है। कहें कि मेरे पास LIST = a_old_tt x_old_da a_new_da q_ty_we है। मैं LIST सामग्री को क्रमबद्ध करना चाहता हूं: LIST_OLD जिसमें LIST के सभी सदस्यों को अभिव्यक्ति पुरानी (a_old_tt और x_old_da मेरे उदाहरण में), और LIST_NOT_OLD शामिल है जिसमें LIST के सभी सदस्यों को अभिव्यक्ति पुरानी नहीं है (a_new_da q_ty_we इन मेरा उदाहरण)। – user1654361

उत्तर

1

मेक की सबसे बड़ी कमियों में से एक नियमित अभिव्यक्तियों को संभालने की अपनी खराब क्षमता है। फ़ंक्शन filter और filter-out किसी शब्द के मध्य में "पुराना" नहीं ढूंढ सकता है। मैं इस हैक का सुझाव दूंगा:

NOT_OLD = $(shell echo $(LIST) | sed 's/[^ ]*old[^ ]* *//g') 
OLD = $(filter-out $(NOT_OLD), $(LIST)) 
0

आप अपने खोल की अधिक उन्नत स्ट्रिंग हैंडलिंग क्षमताओं का लाभ उठा सकते हैं। यह मानते हुए कि आप bash है, तो आप अपने makefile में निम्नलिखित इस्तेमाल कर सकते हैं:

LIST := a_old_tt x_old_da a_new_da q_ty_we 
LIST_NOT_OLD := $(shell l=($(LIST)); echo $${l[@]//*old*}) 
LIST_OLD := $(filter-out $(LIST_NOT_OLD),$(LIST)) 

आप how to delete elements from an array based on a pattern में पार्टी स्ट्रिंग प्रतिस्थापन तंत्र का एक विवरण प्राप्त कर सकते हैं। $ को दोहराए जाने के लिए $ को खोलने की आवश्यकता है।

7

आप बिना किसी बाहरी आदेश के इसे कर सकते हैं। परिभाषित दो मैक्रो

containing = $(foreach v,$2,$(if $(findstring $1,$v),$v)) 
not-containing = $(foreach v,$2,$(if $(findstring $1,$v),,$v)) 

अब आप

LIST := a_old_tt x_old_da a_new_da q_ty_we 
LIST_OLD := $(call containing,old,$(LIST)) 
LIST_NOT_OLD := $(call not-containing,old,$(LIST)) 
+0

+1, उचित दिखता है, व्यक्तिगत रूप से मैं इसे उसी तरह लागू करता हूं। –

+0

सीमित 'अगर' बूलियन की गणना करने के लिए आपको पूर्ण नियमित अभिव्यक्ति की आवश्यकता है, लेकिन यह इस विशेष मामले के लिए काम करता है। मैं व्यक्तिगत रूप से बाह्य आदेशों के बारे में चिंता नहीं करता, क्योंकि मेक का प्रदर्शन/आंतरिक लूप निर्माण/संकलन आदेश में, लक्ष्य में सबसे अधिक संभावना है। –

+0

निश्चित रूप से, जैसा कि बीटा ने अपने जवाब में कहा था, 'मेक' नियमित अभिव्यक्तियों से बिल्कुल निपट नहीं सकता है, इसलिए यदि आपको उनकी आवश्यकता है (लेकिन ओपी नहीं करता है), तो आप स्पष्ट रूप से इस उत्तर का उपयोग नहीं कर सकते हैं। इस समस्या की पहली प्रतिक्रिया अक्सर बड़ी बंदूकें लाने और मिलान करने के लिए बाहरी कमांड का आह्वान करने के लिए होती है, लेकिन जैसा कि इस मामले से पता चलता है, यह बहुत अधिक हो सकता है। पोर्टेबिलिटी और गति दोनों के लिए जितना संभव हो सके बाहरी आदेशों को चलाने से बचें। मैंने बड़ी मेक-आधारित बिल्ड सिस्टम में अनावश्यक बाह्य कमांड से छुटकारा पाने से भारी प्रदर्शन लाभ देखा है। – Idelic