2013-04-22 4 views
13

सॉर्ट किए बिना डुप्लिकेट शब्दों को हटाएं क्या को मेकफ़ाइल में सॉर्ट किए बिना शब्दों की सूची में डुप्लिकेट को हटाने की संभावना है?मेकफ़ाइल:

$(sort foo bar lose) 

डुप्लिकेट (जो मेरे लिए इस मामले में मुख्य कार्यक्षमता है) को हटाने करता है, लेकिन यह भी (मेरे लिए इस मामले में एक दुर्भाग्यपूर्ण पक्ष प्रभाव) क्रमबद्ध करता है। मैं इससे बचना चाहता हूं।

[अद्यतन]

bobbogo के जवाब बहुत अच्छी तरह से काम करता है। V3.81 के लिए define uniq का उपयोग करना याद रखें और बाद में संस्करणों के लिए define uniq = पर यह जांच नहीं की गई।

larsmans 'जवाब बहुत अच्छी तरह से भी काम करता है अगर अपने रिकॉर्ड विभाजक एक अंतरिक्ष, उदा नहीं है यदि आप _foo_bar_lose_lose_bar_baz_ या इसी तरह से डुप्लिकेट को हटाना चाहते हैं। बस tr के बजाय RS और ORS awk विकल्पों का उपयोग, और यह सब लपेट $(firstword $(shell ...))

+2

कोई भी अंतर्निहित ऑपरेशन नहीं है जो ऐसा कर सकता है। आपको एक खोल ऑपरेशन का उपयोग करना होगा। – MadScientist

उत्तर

17

बोरिंग $eval आधारित विधि:

define uniq = 
    $(eval seen :=) 
    $(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_))) 
    ${seen} 
endef 

w := z z x x y c x 

$(info $(sort $w)) 
$(info $(call uniq,$w)) 

अत्यंत पैशाचिक मेकअप मानक पुस्तकालय पुनरावर्ती कॉल ("पुनरावर्ती मेकअप बेहद पैशाचिक माना ?):

uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))) 
+1

मुझे खेद है, यह काम नहीं प्रतीत होता है। $ (जानकारी $ (सॉर्ट करें $ डब्ल्यू)) सॉर्ट किए गए सरणी को प्रिंट करता है, लेकिन $ (जानकारी $ (कॉल यूनिक, $ डब्ल्यू)) कुछ भी प्रिंट नहीं करता है। हालांकि, मुझे यह एक बहुत चालाक समाधान मिल गया है। शायद यह केवल एक छोटा संशोधन की आवश्यकता है? – parvus

+0

@parvus आप किस संस्करण का उपयोग कर रहे हैं? '$ (eval ...)' अपेक्षाकृत हाल ही में है, हालांकि मुझे लगता है कि फाइनेंशियल समाधान अपेक्षाकृत पोर्टेबल होना चाहिए। – bobbogo

+1

'परिभाषित blah = 'और भी हाल ही में है। शायद बस '=' ले लो? – bobbogo

6

साथ करने के लिए आप awk के माध्यम से शब्द echo सकता है याद रखें:

echo foo bar foo baz bar | tr ' ' '\n' | awk '!a[$0]++' 

एक लाइनर catonmat से लिया Deduping।

(। एक Makefile में $$ को $ दोगुना करने के लिए मत भूलना)

+1

ठीक टीएक्स! लेकिन मैं एक स्ट्रिंग में परिणाम कैसे प्राप्त कर सकता हूं? Awk परिणामों को न्यूलाइन के साथ देता है, और मुझे परिणाम एक चर में संग्रहीत करने की आवश्यकता है ताकि मैं इसे चारों ओर पास कर सकूं। – parvus

+1

@parvus: एक अतिरिक्त '| अंत में tr '\ n' '' 'ऐसा करना चाहिए। (बहुत सुंदर नहीं, मैं मानता हूं।) –

+0

दुर्भाग्यवश, ऐसा नहीं है। इसके बाद उद्धरण के बिना "बाज़" आउटपुट होता है। संभावना है कि जब से मैं एक बेवकूफ डॉस खोल में कोशिश करता हूं (कुछ पोर्टेड GnuWin32 उपयोगिताओं जैसे awk और tr और ऐसे)। मैंने लिनक्स सिस्टम पर इसे आजमाया नहीं है, क्योंकि इस ऑपरेशन को विंडोज़-केवल पर्यावरण में जरूरी है। – parvus

5

इस पर निर्भर करता है कि आपको इसकी आवश्यकता है और क्या आप जीएनयू बनाने का उपयोग करते हैं। तुम सिर्फ लक्ष्य आवश्यक शर्तें की सूची Uniq चाहते हैं, यह के रूप में (http://www.gnu.org/software/make/manual/make.html#Quick-Reference) के रूप में आसान है:

$^का मूल्य डुप्लिकेट आवश्यक शर्तें को छोड़ देता है, जबकि $ + उन्हें बरकरार रखे हुए है और उनके क्रम को बरकरार रखता है।

तो,

exe: $(OBJS) 
     $(LD) -o [email protected] $^ 

जैसा कोई नियम $ (OBJS) स्वतः से डुप्लिकेट फिल्टर करेगा, जबकि अभी भी अन्य एक ही आइटम के आदेश हो जाता है।