最近項目中需要對埋點日志hive表進行分析,並且按一定的規則統計出來滿足要求的用戶pin。本來以為是一件比較簡單的事,結果在查看導出的詞表時發現很多帶有"%"的明顯具有url encode特征的用戶pin,於是就開啟了這篇文章用hive對字段進行urlDecode的探索。
在查看了一些資料后,剛開始我是選擇直接用reflect函數調用java自帶的URLDecoder方法來對user_pin進行處理的,具體hive sql如下:
hive -e "select reflect('java.net.URLDecoder', 'decode', user_pin, 'UTF-8') as user_pin from table where [condition]"
本來以為解決了問題大功告成了,結果跑數的時候總出現下面這個異常:
URLDecoder異常Illegal hex characters in escape (%)
查看了一下源數據,發現是因為有些用戶pin中本來就帶有"%"導致的(可能是非法攻擊或者埋點上報異常引起),使URLDecode失敗。參照了一下之前java處理URLDecode異常的經驗,想着在url解碼之前對數據先做一些預處理,但是由於reflect基本只有在調用靜態方法的時候才有意義,所以不能直接通過reflect用replaceAll方法。於是想到了用hive自帶的udf中的regexp_replace來替代replaceAll,具體代碼如下:
#如果是用的單引號包裹查詢語句值,需要對!進行處理 sql="select reflect('java.net.URLDecoder', 'decode', regexp_replace(regexp_replace(user_pin, '%(?\\![0-9a-fA-F]{2})', '%25'), '\\\\+', '%2B'), 'UTF-8') from table where [condition]" #如果是用雙引號包裹查詢語句值 sql=''' select reflect("java.net.URLDecoder", "decode", regexp_replace(regexp_replace(user_pin, "%(?![0-9a-fA-F]{2})", "%25"), "\\\\+", "%2B"), "UTF-8") from table where [condition] ''' #執行sql hive -e "$sql"
如果你用的是單引號包裹查詢語句的值的時候,一定要記得對!進行轉義,否則會出現-bash: !": event not found的問題的。
轉載請注明出處:https://www.cnblogs.com/fnlingnzb-learner/p/13442744.html
