2016-09-18 55 views
0

數字線由我場有包含這些字符,在我的分隔符/分隔符是##@##一個文本文件:排序在AWK

Steve##@##Jobs##@##Apple Inc.##@##32421213 
Bill##@##Gates##@##Microsoft Corp.##@##234213 
Steve##@##Wozniak##@##Apple Inc.##@##12343 
Tim##@##Cook##@##Apple Inc.##@##323345223 

現在,我希望他們能夠被第三場數值&升序。我讀到可以使用bash命令sort,這不幸只支持單個字符作爲分隔符。

最終排序的文件應該正好是這樣的一個:

Steve##@##Wozniak##@##Apple Inc.##@##12343 
Bill##@##Gates##@##Microsoft Corp.##@##234213 
Steve##@##Jobs##@##Apple Inc.##@##32421213 
Tim##@##Cook##@##Apple Inc.##@##323345223 

是否有某種修復或我可以做到這一點使用AWK?

回答

2

這裏有一個(黑客)的想法。使用awk將數字字段添加到每行的開頭,以便我們可以用sort對其進行分類,然後使用sed來擺脫我們在第一步中添加的內容。類似的東西:

awk -vFS='##@##' '{print $4 "|" $0}' input | sort -n | sed -e 's/^[^|]*|//' 
+0

這是標準的方法,但是使用'\ t'代替'|'作爲分隔符,因爲這是默認的'sort'分隔符,這樣你就可以告訴排序只使用第一個字段(因爲YMMV的順序是'|'vs其他字符),所以你可以在之後使用它的默認分隔符:'awk -F'## @ ##'-v OFS ='\ t''{print $ 4,$ 0}'輸入| sort -k1,1n |切-f2-'。 –

0

使用perl解,無需其他命令

$ cat ip.txt 
Steve##@##Jobs##@##Apple Inc.##@##32421213 
Bill##@##Gates##@##Microsoft Corp.##@##234213 
abc##@##xyz##@##123 Corp.##@##234213 
Steve##@##Wozniak##@##Apple Inc.##@##12343 
Tim##@##Cook##@##Apple Inc.##@##323345223 

$ perl -ne '($k)=/(\d+)$/; $h{$k} .= $_; END{foreach (sort {$a <=> $b} keys %h){print $h{$_}}}' ip.txt 
Steve##@##Wozniak##@##Apple Inc.##@##12343 
Bill##@##Gates##@##Microsoft Corp.##@##234213 
abc##@##xyz##@##123 Corp.##@##234213 
Steve##@##Jobs##@##Apple Inc.##@##32421213 
Tim##@##Cook##@##Apple Inc.##@##323345223 
  • 在線的端部的數量被用作一個關鍵
  • 輸入線的追加到哈希可變基於密鑰,也可以處理多個具有相同密鑰的行
  • 處理所有行後,密鑰將按數字排序,並且相應的值將打印d出
0

因爲排序(1)只接受一個單字符分隔符,你想你的分隔字符串轉換成什麼類型​​的認識,而不是出現在您的數據的值。您的最佳選擇是不能在數據中出現:不可打印的字符。一個合理的候選人是ASCII字段分隔符,八進制034.那麼當然你必須在分類後恢復你的分隔符。

如果您使用bash,您可以通過八進制值直接訪問字符,否則您的shell可能會有所不同。然後sed的可迅速:

$ s=$'\034' 
$ sed "s/##@##/$s/g" dat | sort -t $s -k4 -n | sed "s/$s/##@##/g" 

Steve##@##Wozniak##@##Apple Inc.##@##12343 
Bill##@##Gates##@##Microsoft Corp.##@##234213 
Steve##@##Jobs##@##Apple Inc.##@##32421213 
Tim##@##Cook##@##Apple Inc.##@##323345223