2013-04-22 30 views
13

メイクファイルでをソートせずに単語のリスト内の重複を削除する可能性はありますかmakefile:ソートせずに重複する単語を削除する

$(sort foo bar lose) 

(私のためにここでは不幸な副作用)(私のために、この場合の主な機能である)複製だけでなく、ソートを削除しません。私はそれを避けたい。

[更新]

bobbogoの答えは非常にうまく動作します。 v3.81にはdefine uniqを使用し、それ以降のバージョンにはdefine uniq =(これをチェックしなかった)を覚えておいてください。

はあなたのレコードセパレータはスペース、例えばない場合は「答えはあまりにも非常にうまく動作しますlarsmans _foo_bar_lose_lose_bar_baz_などから重複を削除する場合は、ただ、代わりにtrRSORS awkのオプションを使用することを忘れないでください、とあなたがawkを通じて言葉をechoでき$(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

申し訳ありませんが、これは動作していないようです。 $(info $(sort $ w))はソートされた配列を出力しますが、$(info $(call uniq、$ w))は何も出力しません。私はそれが非常に巧妙な解決策を見つける。おそらくそれはわずかな変更を必要とするでしょうか? – parvus

+0

@parvusどのバージョンのメイクを使用していますか? '$(eval ...)'は比較的最近のことですが、私はフィレンシズ的解決策は比較的移植性があると考えています。 – bobbogo

+1

'define blah ='はもっと最近です。多分 '='を取り除くのでしょうか? – bobbogo

6

でそれすべてを包む:

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

ワンライナーはcatonmatから取ら重複除去。

(。Makefileの$$$を倍増することを忘れないでください)

+1

Ok tx!しかし、どうすれば結果を1つの文字列に戻すことができますか? Awkは改行で結果を返します。その結果を変数に格納して渡すことができます。 – parvus

+1

@parvus:余分な '| tr '\ n' '' '最後にそれを行う必要があります。 (それほどエレガントではない、と私は認めます) –

+0

残念ながら、それはありません。その後、 "baz"を引用符なしで出力します。私は愚かなDOSシェル(awkやtrなどの移植されたGnuWin32ユーティリティをいくつか使っています)でこれを試しています。私はLinuxシステム上で試してみませんでした。この操作はWindowsのみの環境では必要です。 – parvus

5

あなたが必要な場所とGNU makeを使用するかどうかによって異なります。あなただけのターゲットの前提条件のリストをUNIQしたい場合は、それが(http://www.gnu.org/software/make/manual/make.html#Quick-Reference)と同じくらい簡単です:$ +はそれらを保持し、その順序を保持しながら

$ ^の値は、重複した前提条件を省略します。

まだ同じ他の項目の順序を残したままので、

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

のようなルールは、自動的に$(OBJS)から重複をフィルタします。

関連する問題