2012-01-12 28 views
3

我想加入bash中的兩個文件。我想保留這兩個文件中的所有可配對和不可配對的行。不幸的是使用join我可以從一個文件中保存不可配對的字段,例如。 join -1 1 -2 2 -a1 -t" "
我也想保留所有配對重複條目(在連接列)從這兩個文件。 也就是說如果file1
X ID1 AB
X ID1 CD
X ID1 DF
X id2的CX
X ID3 FV
像SAS一樣加入bash

和第二文件是

ID1 DF CF
ID1 DS DG
id2 cv df
id2 as ds
id3 cf cg

生成的文件應該是:

X ID1 AB DF CF
X ID1 AB DS DG
X ID1 CD DF CF
X ID1 CD DS DG
X ID1 DF DF CF
X ID1 DF DS DG
X ID2 CX CV DF
X ID2 CX作爲DS
X ID3 FV CF CG

這就是爲什麼我一直使用SAS做出這樣的加入,適當的排序列後。

data x;
merge file1 file2;
by common_column;
run;

它工作正常,但
1.我使用Ubuntu的大部分時間,我切換到Windows在SAS數據合併。
2.最重要的是,SAS可以截斷太長的數據條目。

這就是爲什麼我更願意以bash加入我的文件,但我不知道適當的命令。
有人可以幫我,或指導我適當的資源嗎?

+2

SAS的最大可變長度爲32767個字符。所以,如果你遇到截斷問題,你的文件不是那麼寬泛,那麼別的東西就出錯了。您可能需要將'lrecl = 32767'語句添加到您的文件名或infile語句中。 – 2012-01-12 17:27:42

+0

我已經使用了導入嚮導,我可以在其中指定「猜測行數」的字段,導入期間SAS會掃描此行並根據找到的最長記錄分配變量的長度。我會嘗試使用代碼和您的建議導入。 – boczniak767 2012-01-12 21:30:23

回答

4

根據join的手冊頁,-a <filenum>保留文件<filenum>(1或2)中的所有不可配對的行。所以,只需在您的命令行中添加-a1 -a2即可完成。例如:

# cat a 
1 blah 
2 foo 

# cat b 
2 bar 
3 baz 

# join -1 1 -2 1 -t" " a b 
2 foo bar 

# join -1 1 -2 1 -t" " -a1 a b 
1 blah 
2 foo bar 

# join -1 1 -2 1 -t" " -a2 a b 
2 foo bar 
3 baz 

# join -1 1 -2 1 -t" " -a1 -a2 a b 
1 blah 
2 foo bar 
3 baz 

這是你在找什麼?

編輯:

既然你提供更詳細,這裏是如何產生的所需輸出(注意,我的文件a是你的第一個文件,我的文件b你的第二個文件,我不得不扭轉-1 1 -2 2到-1 2 -2 1加入id)。我添加了一個字段列表來格式化輸出 - 注意'0'是其中的連接字段:

# join -1 2 -2 1 -o 1.1,0,1.3,1.4,2.2,2.3 a b 

產生你給出的。添加-A1-A2保留兩個文件,那麼你得到兩行unpairable線(你可以猜到他們從我的測試數據):

x id4 u t 
id5 ui oi 

這是相當不可讀的,因爲任何離開了現場只是一個空間。因此,讓我們用替換它們「 - 」,導致:

# join -1 2 -2 1 -a1 -a2 -e- -o 1.1,0,1.3,1.4,2.2,2.3 a b 
x id1 a b df cf 
x id1 a b ds dg 
x id1 c d df cf 
x id1 c d ds dg 
x id1 d f df cf 
x id1 d f ds dg 
x id2 c x cv df 
x id2 c x as ds 
x id3 f v cf cg 
x id4 u t - - 
- id5 - - ui oi 
+0

這幾乎是完美的解決方案。幾乎 - 因爲需要列的規格。我的真實文件分別有15列和4列。所以說規範不是很方便。但工作,所以我接受你的迴應 - 謝謝。 – boczniak767 2012-01-12 23:27:33

1

如果join命令功能不夠強大,我通常使用sqlite如果我需要在外殼執行這樣的操作。

您可以輕鬆地將平面文件導入表格,然後使用正確的JOIN做SQLSELECT

請注意,使用sqlite,您可以利用索引使聯接更加快速

sqlite3 << EOF! 
CREATE TABLE my table1 (.... -- define your table here 
CREATE TABLE my table2 (.... -- define your table here 
.separator "," -- define input field separator here if needed 
.import input_file.txt mytable1 
.import input_file.txt mytable2 
SELECT ... JOIN ... 
EOF! 

sqlite是免費的多平臺。非常便利。

+0

我不喜歡爲每一個任務安裝新軟件,但是誰知道,也許如果我必須做很多合併,這將是有益的。 – boczniak767 2012-01-12 23:29:39

+0

@MaciejJończyk:sqlite很小且方便。無論如何,這是值得的:-) – 2012-01-12 23:50:16