2013-05-22 47 views
0

這是我的Hadoop工作:awk不Hadoop中的映射工作

hadoop streaming \ 
-D mapred.map.tasks=1\ 
-D mapred.reduce.tasks=1\ 
-mapper "awk '{if(\$0<3)print}'" \ # doesn't work 
-reducer "cat" \ 
-input "/user/***/input/" \ 
-output "/user/***/out/" 

此作業總是失敗,有一個錯誤說:

sh: -c: line 0: syntax error near unexpected token `(' 
sh: -c: line 0: `export TMPDIR='..../work/tmp'; /bin/awk { if ($0 < 3) print } ' 

但是,如果我改變-mapper成這樣: -mapper「awk」{print}'「 它沒有任何錯誤。 if(..)有什麼問題?

更新:

感謝@paxdiablo爲您的詳細解答。

在將輸入數據傳輸到我的自定義bin之前,我真正想要做的是過濾掉第一列大於x的一些數據。所以-mapper實際上看起來像這樣:

-mapper "awk -v x=$x{if($0<x)print} | ./bin" 

有沒有其他方法可以實現這一目標?

+0

順便提一下,Alcott'$ 0'是整個輸入行。如果你只想要第一個字段,那就是$ 1。 – paxdiablo

回答

1

該問題與if本身不符,這是因爲您的命令中的引號已從您的awk命令中刪除。

,當你在錯誤輸出你會認識到這一點:

sh: -c: line 0: `export TMPDIR='..../work/tmp'; /bin/awk { if ($0 < 3) print } ' 

,當您嘗試執行直接在報價剝命令:

pax> echo hello | awk {if($0<3)print} 
bash: syntax error near unexpected token `(' 

pax> echo hello | awk {print} 
hello 

的原因{print}一個作品是因爲它不包含外殼特殊的(字符。你可能想嘗試

一件事是逃跑的特殊字符,以保證外殼不會試圖解釋它們:

{if\(\$0\<3\)print} 

這可能需要一些努力得到正確轉義字符串,但你可以查看錯誤輸出以查看生成的內容。我不得不逃脫(),因爲它們是shell子shell創建命令,$防止可變擴展,而<防止輸入重定向。


還銘記保持,有可能是其他的方式取決於篩選你的需求,就是能夠避免殼特殊字符的方式。如果您指定了您的需求,我們可以進一步提供幫助。

例如,您可以創建一個shell腳本(如pax.sh)爲你做的實際awk工作:

#!/bin/bash 
awk -v x=$1 'if($1<x){print}' 

然後使用shell腳本映射器中沒有任何特殊的shell字符:

hadoop streaming \ 
    -D mapred.map.tasks=1 -D mapred.reduce.tasks=1 \ 
    -mapper "pax.sh 3" -reducer "cat" \ 
    -input "/user/***/input/" -output "/user/***/out/" 
+0

是的,你是對的,但有什麼辦法解決它? – Alcott

+0

謝謝,我已經更新了我的帖子,增加了我的真正目的。 – Alcott

+0

@Alcott,我添加了一個可能使其可行的可能性。查看更新後的答案。 – paxdiablo