Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux - join 2 CSV files

Tags:

linux

join

csv

I have 2 CSV files:

file_1 columns: id,user_id,message_id,rate
file_2 columns: id,type,timestamp

The relation between the files is that file_1.message_id = files_2.id.

I want to create a 3rd file that will have the following columns:

file_1.id,file_1.user_id,file_1.message_id,file_1.rate,file_2.timestamp

Any ideas on how to do this in Linux?

like image 880
Ran Avatar asked Jan 11 '12 14:01

Ran


2 Answers

You can use the join command like this:

join -t, -1 3 -2 1 -o 1.1 1.2 1.3 1.4 2.3 <(sort -t, -k 3,3 file1) <(sort file2)

It first sorts the files (file1 is sorted by the 3rd field) and then joins them using the 3rd field of file1 and the 1st field of file2. It then outputs the fields you need.

like image 50
dogbane Avatar answered Oct 08 '22 15:10

dogbane


Seems to be a job for SQLite. Using the SQLite shell:

 create table f1(id,user_id,message_id,rate);
 create table f2(id,type,timestamp);

 .separator ,
 .import 'file_1.txt' f1
 .import 'file_2.txt' f2

 CREATE INDEX i1 ON f1(message_id ASC); -- optional
 CREATE INDEX i2 ON f2(id ASC);         -- optional

 .output 'output.txt'
 .separator ,

 SELECT f1.id, f1.user_id, f1.message_id, f1.rate, f2.timestamp
   FROM f1
   JOIN f2 ON f2.id = f1.message_id;

 .output stdout
 .q

Note that if there is a single error in the number of commas in a single line the import stage will fail. You can prevent the rest of the script from running with .bail on at the script beginning.

If you want unmatched ids you can try:

SELECT f1.* FROM f1 LEFT JOIN f2 on f2.id = f1.message_id WHERE f2.id IS NULL

Which will select every row from f1 for which no corresponding row in f2 has been found.

like image 36
Benoit Avatar answered Oct 08 '22 14:10

Benoit