2015-10-05 96 views
1

我想根據另一列的值將列轉置爲若干較小的部分,例如,基於另一列的值將一列轉置爲行

1 ID1 V1 
2 ID1 V2 
3 ID1 V3 
4 ID2 V4 
5 ID2 V5 
6 ID3 V6 
7 ID3 V7 
8 ID3 V8 
9 ID3 V9 

我希望有所有V值爲每個ID是在一行中例如

ID1 V1 V2 V3 
ID2 V4 V5 
ID3 V6 V7 V8 V9 

每個id具有不同的轉置行數,如示例中所示。如果使用序列號列更容易執行此操作,那麼也可以。

任何人都可以幫忙嗎?

回答

1

下面是一個簡單的awk的一行這樣的伎倆:

awk '1 {if (a[$2]) {a[$2] = a[$2]" "$3} else {a[$2] = $3}} END {for (i in a) { print i,a[i]}}' file.txt 

輸出:

ID1 V1 V2 V3 
ID2 V4 V5 
ID3 V6 V7 V8 V9 
+0

謝謝@pcantalupo,這是超級簡單,但偉大的!有沒有辦法使用另一個「密鑰」文件轉置此文件?密鑰文件有三列提供關於該文件的信息,即:「ID號」,「起始行」和「結束行」。例如密鑰文件的前三行如下所示:ID1 1 3 ID2 4 5 ID3 6 9等等。 – Schuman

+0

要麼更新此問題,要麼將其作爲另一個問題發佈 – pcantalupo

0

如果您喜歡在JavaScript編碼,這是如何使用的JLine做它的命令行:https://github.com/bitdivine/jline/

[email protected]:~$ cat ,,, | jline-foreach 'begin::global.all={}' line::'fields=record.split(/ +/);if(fields.length==3)tm.incrementPath(all,fields.slice(1))' end::'tm.find(all,{maxdepth:1},function(path,val){console.log(path[0],Object.keys(val).join(","));})' ID1 V1,V2,V3 ID2 V4,V5 ID3 V6,V7,V8,V9

該輸入是: [email protected]:~$ cat ,,, 1 ID1 V1 2 ID1 V2 3 ID1 V3 4 ID2 V4 5 ID2 V5 6 ID3 V6 7 ID3 V7 8 ID3 V8 9 ID3 V9 [email protected]:~$

說明:這將構建一個樹第一級分支是用戶ID,第二級是V(版本?)。你可以爲任何級別做到這一點。葉子只是櫃檯。首先,我們創建一個空的樹:

'begin::global.all={}'

然後就是進來被分爲計數器,ID和版本號的每一行。計數器被切掉只留下數組[用戶ID,版本]。 incrementCounter創建樹,有點像mkdir -p這些分支,雖然你實際上並不需要知道如何往往是每個用戶,版本組合已經看到增加的葉計數器:

line::'fields=record.split(/ +/);if(fields.length==3)tm.incrementPath(all,fields.slice(1))' end::'tm.find(all,{maxdepth:1},function(path,val){console.log(path[0],Object.keys(val).join(","));})'

在結束我們有tm.find其行爲就像UNIX查找並打印樹中的每個路徑。除了我們將搜索的深度限制到期望的分解點(1,但是如果你像我一樣,接下來你會想要分解2,3,5或8個變量)。通過這種方式,您可以分解出故障點和值的列表,並且可以打印答案。

如果你永遠不需要更深入的分解,你可能會想要堅持使用awk,因爲它可能是預先安裝的。