2017-06-27 30 views
-3

比如我有一個文件:如何通過鍵將多個字符串摺疊爲一個?

key1 1212 
key2 1212 
key1 32332 
key2 3232 
key2 3232 

我想獲得的文件:

key1 1212,32332 
key2 1212,3232,3232 
+0

這應該是在bash可能的,但我會建議,而不是破壞你的大腦 - 使用更好的工具,如果你問慶典 - 它的Linux - 肯定有Python - 使用它 - 任務變得簡單。 – Drako

+0

添加了awk和python標籤,因爲我的答案中有評論。 –

回答

1

在awk中:

$ awk '{a[$1]=a[$1](a[$1]==""?"":",")$2}END{for(i in a)print i,a[i]}' file 
key1 1212,32332 
key2 1212,3232,3232 

解釋:

awk '{          # use awk for this kind of stuff 
    a[$1]=a[$1] (a[$1]=="" ? "" : ",") $2 # hash on first col and append seconds 
} 
END {           # after everything is hashed 
    for(i in a)        # for each entry in hash a 
     print i,a[i]       # output key and data 
}' file          # oh yeah the file 

編輯:而不是讓awk做緩衝(即。散列爲a),我們可以使用sort對文件進行排序,然後輸出密鑰和逗號分隔後的所有數據。再次使用AWK後者部分:

$ sort file | awk '$1!=p{printf "%s%s",(NR>1?ORS:""),$1}{printf "%s%s", ($1==p?",":OFS),$2;p=$1}END{print ""}' 
key1 1212,32332 
key2 1212,3232,3232 

這裏sort沒有給出任何花哨的參數,但是在現實世界中的一些可能是必需的。 awk的部分解釋:

sort file | \       # sort the file 
awk '         # before feeding to awk 
$1!=p {        # if key is different from previous key 
    printf "%s%s",(NR>1?ORS:""),$1  # newline and print the key 
} 
{ 
    printf "%s%s", ($1==p?",":OFS),$2 # print the data comma-separated 
    p=$1        # store key for comparing on the next round 
} 
END{ 
    print ""       # finish the last line nicely 
}' 
+0

答案最有可能是好的和工作,但我總是試着讓人們遠離用bash解析文本文件 - 這是效率低下的。你不知道這個輸入文件有多大,所以它可能非常糟糕:)和Bdfy,考慮到你的SO聲望 - 如果你添加標籤python到你的問題我將提供工作python解決方案,我認爲比bash更好用。 – Drako

+0

@Drako:話雖如此,'awk'對於小文件來說是完美無缺的 – sjsam

+1

@sjsam我同意,但是如果輸入將會是500MB或更多,那麼您真的會對python解決方案感到更開心:)這就是爲什麼即使對於小我也傾向於如果可能,請使用正確的工具,因爲你永遠不知道它何時會增長:) – Drako

0
awk '{a[$1]=(a[$1]!="")?a[$1]","$2:$2}END{for(i in a){print i "\t" a[i]}}' file 
key1 1212,32332 
key2 1212,3232,3232 

應該這樣做。

0

如果您想避免緩存整個文件的結果(例如文件非常大),您可以使用sort和Python的itertools.groupby。像這樣創建一個Python腳本:

# group.py 

import itertools, sys 

for k, g in itertools.groupby(sys.stdin, lambda x: x.split()[0]): 
    print(k, ",".join([x.split()[1] for x in g])) 

然後運行:

perl -aE 'push @{$h{$F[0]}}, $F[1]; END {$"= ","; say "$_ @{$h{$_}}" for sort keys %h}' file 

sort file | python group.py 
key1 1212,32332 
key2 1212,3232,3232 

否則,這種快速Perl的一個班輪應在哈希累計值以及工作輸出:

key1 1212,32332 
key2 1212,3232,3232 
0

它不是純粹的sh/coreutils的,但可以考慮使用datamash此任務:

sed -r -e 's/[[:space:]]+/ /g' < infile.txt | datamash -t ' ' -s groupby 1 collapse 2 
相關問題