2014-01-19 57 views
3

我必須處理許多('00s)兩列分隔的文件,它們的第一列(例如長整型,範圍可以從857到293823421)按數字排序。unix是否嚴格加入詞彙?

的處理很簡單:遍歷循環中使用其中一個作爲「錨」(在加入「左」文件)到左加入文件,使用join-e-o選項填寫NULL。

問題:是否有任何方法join(來自Core Utils 8.13)可以按原樣處理這些連接,還是必須添加sort -k1,1步驟以確保每次連接之前的詞彙順序?

我讀過的所有東西都在搜索中,這告訴我我必須這樣做,但是我想確保我不會錯過一些巧妙的技巧來避免額外的排序。謝謝。

回答

2

事實上,join不支持數字比較。然而,從你的描述來看,這聽起來像你可以通過零填充將你的第一個字段轉換爲已經字符串排序的表單,然後通過對它進行零填充來將其轉換回來。例如,下面是執行join -e NULL兩個符合您的描述是(據我所知)文件功能:

function join_by_numeric_first_field() { 
    local file1="$1" 
    local file2="$2" 
    join -e NULL <(awk '{printf("%020d\t%s\n", $1, $2)}' "$file1") \ 
       <(awk '{printf("%020d\t%s\n", $1, $2)}' "$file2") \ 
    | awk '{printf("%d\t%s\n", $1, $2)}' 
} 

(該awk '{printf("%020d\t%s\n", $1, $2)}'讀取兩列輸入,並重新打印出的每一行兩列,用製表符分隔,但將第一列作爲十進制整數,並將其填充爲二十個字符。awk '{printf("%d\t%s\n", $1, $2)}'做同樣的事情,除了它不是不是零填充十進制整數,所以它具有剝離任何零填充的效果)

這是否比更好0 -ing將取決於文件的大小,以及您需要如何靈活支持與描述不完全匹配的文件。這種方法與文件大小成線性關係,但是要複雜得多,而且更加脆弱,因爲awk命令需要一個非常明確的輸入格式。 sort的方法要簡單得多,但對於大文件來說效果不佳。

+0

+1但請注意'<(cmd)'是一個Bashism,並且在其他shell中不起作用。如果(正如你的標籤所暗示的那樣)真正的Unix可移植性是一個問題,你可以用臨時文件來解決這個問題......但是,然後簡單地按詞彙排序你的輸入可能是阻力和/或痛苦最小的路徑。 – tripleee

+0

謝謝你的想法和代碼。我會用兩種方法(文件相當大,絕對值得運行比較)。 – user2105469