2013-10-19 49 views
0

如何獲得兩個.csv文件之間的相交線? 我的問題似乎很難理解,但我會給你一個這樣的例子:如何獲取兩個.csv文件之間的相交線?

我有2個的.csv文件:

 
+---+-------+----+  +-----------------+ 
| A | B | C |  | A | B | C | 
+---+-------+----+  +----+-------+----+ 
| 1 | ant | 14 |*  | 6 | Fan | 12 | 
| 2 | bird | 11 |  | 7 | gun | 55 |* 
| 3 | cat | 21 |*  | 8 | horse | 21 |* 
| 4 | dog | 55 |*  | 9 | ice | 15 | 
| 5 | egg | 99 |  | 10 | jar | 14 |* 
+---+-------+---+  +----+-------+----+ 
    Table 1     Table 2 

所以,如果我用表1至表篩選2我得到的輸出是這樣的:

 
+----------------+ 
| A | B | C | 
+---+-------+----+  
| 7 | gun | 55 |*  
| 8 | horse | 21 |*  
| 10| jar | 14 |*  
+---+-------+----+  
    Table 3     

是的,我用表1的最後一列的表2

過濾器如何過濾它如T他用任何工具?

+0

你的文件有多大?你可以使用宏嗎?你可以使用MS-Access或任何其他RDBM? – NoChance

+0

@EmmadKareem大約有幾十萬到幾百萬行。 – fronthem

+1

我會用這個任務的數據庫。 – NoChance

回答

1

按照上述評論,這裏是我做過什麼:

Create table T1 (A INT, B VARCHAR(100), C INT); 

Create table T2 (A INT, B VARCHAR(100), C INT); 

Insert into T1 Values (1, 'ant',14); 
Insert into T1 Values (2, 'bird',11); 
Insert into T1 Values (3, 'cat',21); 
Insert into T1 Values (4, 'dog',55); 
Insert into T1 Values (5, 'egg',99); 

Insert into T2 Values (6, 'fan',12); 
Insert into T2 Values (7, 'gun',55); 
Insert into T2 Values (8, 'horse',21); 
Insert into T2 Values (9, 'ice',15); 
Insert into T2 Values (10, 'jar',14); 

我不知道你是否已經在表中或不中的數據,也有工具來導入CSV文件到您的分貝。

如果您要經常運行查詢,那麼在每個表的列A上構建索引會加快此過程。我沒有爲這個簡單的例子構建任何索引。

選擇需要得到你的結果是:

select * from t2,t1 where t2.c = t1.c order by t2.a 

如果您對結果感到滿意,你可以把它放在一個表像這樣的(SQL Server)的

SELECT T2.A, T2.B , T2.C INTO TEST FROM t2,t1 where t2.c = t1.c order by t2.a 

我希望這是你想要的...

1

假設你的輸入文件就只包含數字和字符串,沒有額外的表格式字符(只是\t分隔的文件),你可以做到以下幾點:

表1(t1.txt):

1  ant  14 
2  bird 11 
3  cat  21 
4  dog  55 
5  egg  99 

表2(t2.txt):

6  Fan  12 
7  gun  55 
8  horse 21 
9  ice  15 
10  jar  14 

而執行和輸出:

$ join -j 3 -o '2.1,2.2,2.3' <(sort -k 3n t1.txt) <(sort -k 3n t2.txt) | sort -n 
7 gun 55 
8 horse 21 
10 jar 14 

或者,如果您有許多列,則可能首先僅提取篩選列,然後再執行選擇本身。此外,您可以輸出join-輸入文件,而不指定初始模式(所有列,在你的情況下)。執行完畢後,只需選擇你真的想顯示(使用cut,例如)列:

$ join -2 15 <(cut -f 15 t1.txt | sort) <(sort -k 15 t2.txt) | sort -n 

通知cut用途\t作爲默認分隔符 - 可與標誌-d <separator>被重新定義。無論如何,正如@EmmadKareem所指出的那樣,使用適當的數據庫來完成這項任務可能會更好 - 因爲它會有幾十次優化,這些優化肯定是您的數十萬/百萬行所需的。

+1

+1。請注意,將輸入文件轉換爲所需的格式並且可以在排序的同時完成。如果連接不止一次完成,則只需預處理一次就合情合理了。 –

+0

@Rubens你可以給我看18列表的命令,並使用第15列進行過濾。 – fronthem

+0

@ terces907我編輯過;請檢查它是否有幫助。 – Rubens

0

這是Perl中的一個腳本來完成你想要的工作。

它通過掃描第一個文件並將第三列的值保存在內存中起作用。然後它掃描第二個文件,並且對於每行讀取,它將第三列的值與內存中的值進行比較,如果匹配,則打印該行。

#!/usr/bin/perl 
use warnings; 
use strict; 
use 5.010; 

my %seen; 

open my $file1_fh, '<', 'file1.txt' 
    or die "Can't open file1.txt $!"; 

while (<$file1_fh>) { 
    chomp; 
    $seen{ (split)[2] } = 1; #assumes line are delimited by whitespace. 
} 

close $file1_fh; 

open my $file2_fh, '<', 'file2.txt' 
    or die "Can't open file2.txt $!"; 


while (<$file2_fh>) { 
    chomp; 
    my $third_column_value = (split)[2]; #assumes line are delimited by whitespace. 
    say if $seen{ $third_column_value }; 
} 

close $file2_fh; 

__END__ 

#OUTPUT 
7 gun 55 
8 horse 21 
10 jar 14 
1

這可能爲你工作(GNU SED):

sed -r 's/(\S+\s?){3}/\/(^\\S+\\s){2}\1$\/p/' file1.csv | sed -nrf - file2.csv 

爲一個文件,是分開的空間或選項卡。

對於是逗號分隔的文件:

sed -r 's/([^,]+,?){3}/\/(^[^,]+,){2}\1$\/p/' file1.csv | sed -nrf - file2.csv 

這是通過創建從第一個表sed腳本,然後使用它來過濾對第二個表。

相關問題