Merge two files based on matching criteria


 
Thread Tools Search this Thread
Operating Systems Linux Merge two files based on matching criteria
# 1  
Old 09-28-2016
Merge two files based on matching criteria

Hi,
I am trying to merge two csv files based on matching criteria:
File description is as below :
Key_File :
Code:
000|ÇÞ|Key_HF|ÇÞ|Key_FName		
001|ÇÞ|Key_11|ÇÞ|Sort_Key22|ÇÞ|Key_31
002|ÇÞ|Key_12|ÇÞ|Sort_Key23|ÇÞ|Key_32
003|ÇÞ|Key_13|ÇÞ|Sort_Key24|ÇÞ|Key_33
050|ÇÞ|Key_15|ÇÞ|Sort_Key25|ÇÞ|Key_34
085|ÇÞ|Key_15|ÇÞ|Sort_Key26|ÇÞ|Key_35|ÇÞ|Key_41|ÇÞ|Key_42
090|ÇÞ|Key_19|ÇÞ|Sort_Key27
095|ÇÞ|Key_19|ÇÞ|Sort_Key28
100|ÇÞ|Key_11|ÇÞ|Sort_Key29
300|ÇÞ|Key_10|ÇÞ|Sort_Key30
400|ÇÞ|Key_14|ÇÞ|Sort_Key31
500|ÇÞ|Key_15|ÇÞ|Sort_Key32
999|ÇÞ|Key_SS|ÇÞ|

Value_File:
Code:
000|ÇÞ|Val_HF|ÇÞ|Value_FName		
001|ÇÞ|Val_11|ÇÞ|Sort_Val22|ÇÞ|Val_31
002|ÇÞ|Val_12|ÇÞ|Sort_Val23|ÇÞ|Val_32
003|ÇÞ|Val_13|ÇÞ|Sort_Val24|ÇÞ|Val_33
050|ÇÞ|Val_15|ÇÞ|Sort_Val25|ÇÞ|Val_34
085|ÇÞ|Val_15|ÇÞ|Sort_Val26|ÇÞ|Val_35|ÇÞ||ÇÞ|null
090|ÇÞ|Val_19|ÇÞ|Sort_Val27
095|ÇÞ|Val_19|ÇÞ|Sort_Val28
100|ÇÞ|Val_11|ÇÞ|Sort_Val29
300|ÇÞ|Val_10|ÇÞ|Sort_Val30
400|ÇÞ|Val_14|ÇÞ|Sort_Val31
500|ÇÞ|Val_15|ÇÞ|Sort_Val32
999|ÇÞ|Val_SS|ÇÞ|

Here |ÇÞ| is the delimiter.
My output requirement is :
Code:
000|ÇÞ|Key_HF=Val_HF|ÇÞ|Key_FName=Value_FName		
001|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key22=Sort_Val22|ÇÞ|Key_31=Val_31
002|ÇÞ|Key_12=Val_12|ÇÞ|Sort_Key23=Sort_Val23|ÇÞ|Key_32=Val_32
003|ÇÞ|Key_13=Val_13|ÇÞ|Sort_Key24=Sort_Val24|ÇÞ|Key_33=Val_33
050|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key25=Sort_Val25|ÇÞ|Key_34=Val_34
085|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key26=Sort_Val26|ÇÞ|Key_35=Val_35|ÇÞ|Key_41=|ÇÞ|Key_42=null
090|ÇÞ|Key_19=Val_19|ÇÞ|Sort_Key27=Sort_Val27
095|ÇÞ|Key_19=Val_19|ÇÞ|Sort_Key28=Sort_Val28
100|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key29=Sort_Val29
300|ÇÞ|Key_10=Val_10|ÇÞ|Sort_Key30=Sort_Val30
400|ÇÞ|Key_14=Val_14|ÇÞ|Sort_Key31=Sort_Val31
500|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key32=Sort_Val32
999|ÇÞ|Key_SS=Val_SS|ÇÞ|

ie. Compare two files if first column value(001) of Key_file matches with first column value of the Value_file then display the output as key value pair separated by = sign (eg Key_HF=Val_HF)

I tried using below code but not getting the expected output =>
Code:
awk 'NR==FNR{ A[$1]=$2; next } { print $FNR ":" $2 } 1' FS="[|]ÇÞ[|]" Key_File Value_File

Any idea how it will work ??
# 2  
Old 09-28-2016
You might try something like:
Code:
awk '
BEGIN {	FS = "[|]ÇÞ[|]"
	OFS = "|ÇÞ|"
}
NR == FNR {
	for(i = 2; i <= NF; i++)
		v[$1, i] = $i
	next
}
{	printf("%s%s", $1, (NF > 1) ? OFS : ORS)
	for(i = 2; i <= NF; i++)
		printf("%s%s", $i "=" v[$1, i], (NF > i) ? OFS : ORS)
}' Value_File Key_File

which with your sample data produces the output:
Code:
000|ÇÞ|Key_HF=Val_HF|ÇÞ|Key_FName		=Value_FName		
001|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key22=Sort_Val22|ÇÞ|Key_31=Val_31
002|ÇÞ|Key_12=Val_12|ÇÞ|Sort_Key23=Sort_Val23|ÇÞ|Key_32=Val_32
003|ÇÞ|Key_13=Val_13|ÇÞ|Sort_Key24=Sort_Val24|ÇÞ|Key_33=Val_33
050|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key25=Sort_Val25|ÇÞ|Key_34=Val_34
085|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key26=Sort_Val26|ÇÞ|Key_35=Val_35|ÇÞ|Key_41=|ÇÞ|Key_42=null
090|ÇÞ|Key_19=Val_19|ÇÞ|Sort_Key27=Sort_Val27
095|ÇÞ|Key_19=Val_19|ÇÞ|Sort_Key28=Sort_Val28
100|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key29=Sort_Val29
300|ÇÞ|Key_10=Val_10|ÇÞ|Sort_Key30=Sort_Val30
400|ÇÞ|Key_14=Val_14|ÇÞ|Sort_Key31=Sort_Val31
500|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key32=Sort_Val32
999|ÇÞ|Key_SS=Val_SS|ÇÞ|=

which matches what you said you wanted except for the 1st and last lines of the output. If you don' want extraneous <space> characters in the first line of your output, don't include them in both of your input files. And, if you don't want an empty field in the last line in your output, don't include an empty field in the last line of both of your input files.

As always, if you want to try this on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk or nawk.
This User Gave Thanks to Don Cragun For This Post:
# 3  
Old 09-29-2016
for single key and multiple values

How we can handle below scenario in this case(i.e. single key multiple value)
Key_File
Code:
000|ÇÞ|Key_HF|ÇÞ|Key_FName        
001|ÇÞ|Key_11|ÇÞ|Sort_Key22|ÇÞ|Key_31
085|ÇÞ|Key_15|ÇÞ|Sort_Key26|ÇÞ|Key_35|ÇÞ|Key_41|ÇÞ|Key_42
100|ÇÞ|Key_11|ÇÞ|Sort_Key29|ÇÞ|Sort_Key30|ÇÞ|Sort_Key31|ÇÞ|Sort_Key32
300|ÇÞ|Key_10|ÇÞ|Sort_Key30
400|ÇÞ|Key_14|ÇÞ|Sort_Key31
500|ÇÞ|Key_15|ÇÞ|Sort_Key32
999|ÇÞ|Key_SS

Value_File
Code:
000|ÇÞ|Val_HF|ÇÞ|Value_FName        
001|ÇÞ|Val_11|ÇÞ|Sort_Val22|ÇÞ|Val_31
085|ÇÞ|Val_15|ÇÞ|Sort_Val26|ÇÞ|Val_35|ÇÞ||ÇÞ|null
100|ÇÞ|Val_11|ÇÞ|Sort_Val29|ÇÞ|Sort_Val30
100|ÇÞ|Val_11|ÇÞ|Sort_Val29|ÇÞ|Sort_Val30|ÇÞ|Sort_Val31
100|ÇÞ|Val_11|ÇÞ|Sort_Val29|ÇÞ|Sort_Val30|ÇÞ|Sort_Val31|ÇÞ|Sort_Val32
300|ÇÞ|Val_10|ÇÞ|Sort_Val30
400|ÇÞ|Val_14|ÇÞ|Sort_Val31
500|ÇÞ|Val_15|ÇÞ|Sort_Val32
999|ÇÞ|Val_SS

Expected Output :
Code:
000|ÇÞ|Key_HF=Val_HF|ÇÞ|Key_FName=Value_FName        
001|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key22=Sort_Val22|ÇÞ|Key_31=Val_31
085|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key26=Sort_Val26|ÇÞ|Key_35=Val_35|ÇÞ|Key_41=|ÇÞ|Key_42=null
100|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key29=Sort_Val29|ÇÞ|Sort_Key30=Sort_Val30|ÇÞ|Sort_Key31=|ÇÞ|Sort_Key32=
100|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key29=Sort_Val29|ÇÞ|Sort_Key30=Sort_Val30|ÇÞ|Sort_Key31=Sort_Val31|ÇÞ|Sort_Key32=
100|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key29=Sort_Val29|ÇÞ|Sort_Key30=Sort_Val30|ÇÞ|Sort_Key31=Sort_Val31|ÇÞ|Sort_Key32=Sort_Val32
300|ÇÞ|Key_10=Val_10|ÇÞ|Sort_Key30=Sort_Val30
400|ÇÞ|Key_14=Val_14|ÇÞ|Sort_Key31=Sort_Val31
500|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key32=Sort_Val32
999|ÇÞ|Key_SS=Val_SS

Here the requirement is for one key row(100) in Key_File we have multiple values(three 100 rows) in Value_File.
Here Key_File is fixed and Value_File is changing(Can be multiple 100 row values) ..

So can we handle this scenario in this case ?


Moderator's Comments:
Mod Comment Please don't make posts unreadable by using inadequate colours.

Last edited by RudiC; 09-29-2016 at 07:47 AM.. Reason: Changed yellow char colour to red.
# 4  
Old 09-29-2016
Try this adaption of Don Cragun's recent proposal:
Code:
awk '
BEGIN           {FS = "[|]ÇÞ[|]"
                 OFS = "|ÇÞ|"
                }
NR == FNR       {NFK[$1] = NF
                 for(i = 2; i <= NF; i++) v[$1, i] = $i
                 next
                }
                {printf("%s%s", $1, (NF > 1) ? OFS : ORS)
                 for(i = 2; i <= NFK[$1]; i++) printf("%s%s", v[$1, i] "=" $i, (NFK[$1] > i) ? OFS : ORS)
                }
' key_file value_file
000|ÇÞ|Key_HF=Val_HF|ÇÞ|Key_FName        =Value_FName        
001|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key22=Sort_Val22|ÇÞ|Key_31=Val_31
085|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key26=Sort_Val26|ÇÞ|Key_35=Val_35|ÇÞ|Key_41=|ÇÞ|Key_42=null
100|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key29=Sort_Val29|ÇÞ|Sort_Key30=Sort_Val30|ÇÞ|Sort_Key31=|ÇÞ|Sort_Key32=
100|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key29=Sort_Val29|ÇÞ|Sort_Key30=Sort_Val30|ÇÞ|Sort_Key31=Sort_Val31|ÇÞ|Sort_Key32=
100|ÇÞ|Key_11=Val_11|ÇÞ|Sort_Key29=Sort_Val29|ÇÞ|Sort_Key30=Sort_Val30|ÇÞ|Sort_Key31=Sort_Val31|ÇÞ|Sort_Key32=Sort_Val32
300|ÇÞ|Key_10=Val_10|ÇÞ|Sort_Key30=Sort_Val30
400|ÇÞ|Key_14=Val_14|ÇÞ|Sort_Key31=Sort_Val31
500|ÇÞ|Key_15=Val_15|ÇÞ|Sort_Key32=Sort_Val32
999|ÇÞ|Key_SS=Val_SS

This User Gave Thanks to RudiC For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

How to merge two files with unique values matching.?

I have one script as below: #!/bin/ksh Outputfile1="/home/OutputFile1.xls" Outputfile2="/home/OutputFile2.xls" InputFile1="/home/InputFile1.sql" InputFile2="/home/InputFile2.sql" echo "Select hobby, class, subject, sports, rollNumber from Student_Table" >> InputFile1 echo "Select rollNumber... (3 Replies)
Discussion started by: Sharma331
3 Replies

2. Shell Programming and Scripting

How to merge two or more fields from two different files where there is non matching column?

Hi, Please excuse for often requesting queries and making R&D, I am trying to work out a possibility where i have two files field separated by pipe and another file containing only one field where there is no matching columns, Could you please advise how to merge two files. $more... (3 Replies)
Discussion started by: karthikram
3 Replies

3. Shell Programming and Scripting

Merge two files matching columns

Hi! I need to merge two files when col1 (x:x:x) matching and adds second column from file1.txt. # cat 1.txt aaa;a12 bbb;b13 ccc;c33 ddd;d55 eee;e11 # cat 2.txt bbb;b55;34444;d55 aaa;a15;35666;a44 I try with this awk and I get succesfully first column from 1.txt: # awk -F";"... (2 Replies)
Discussion started by: fhluque
2 Replies

4. Shell Programming and Scripting

changing the file-name in a directory for all files matching a particular criteria

i have a directory which consist of multiple files out of which there are some files that has -e in their name. I want to write a script that will change all those file-name to -l example there are some files with name : file1-e.wav file2-e.wav file3-english-e.wav file-4-e.wav ... (3 Replies)
Discussion started by: mukulverma2408
3 Replies

5. UNIX for Dummies Questions & Answers

How to fetch files right below based on some matching criteria?

I have a requirement where in i need to select records right below the search criteria qwertykeyboard white 10 20 30 30 40 50 60 70 80 qwertykeyboard black 40 50 60 70 90 100 qwertykeyboard and white are headers separated by a tab. when i execute my script..i would be searching... (4 Replies)
Discussion started by: vinnu10
4 Replies

6. UNIX for Dummies Questions & Answers

How to select files based on a criteria?

I have a file..... xxx 2345 455 abc 345 555 cdf 456 777 fff 555 888 Now my requirement is, Say if, i want to select only those records prior to the record fff 555 888... how do i go about doing this in unix.... The fff would be hardcoded as it wud be fixed and everytime when i... (7 Replies)
Discussion started by: saggiboy10
7 Replies

7. Shell Programming and Scripting

Archive files to different target folders based on criteria

Hi All, I am creting archive script in which i need to split the source file's to different target folder's based on the input file name first character. Input1.txt -- will contains file names that are needs to be Archive. Input1.txt A1213355 B2255666 C2254555 A6655444 C5566445 ... (2 Replies)
Discussion started by: kmsekhar
2 Replies

8. Shell Programming and Scripting

Script move and rename based on matching criteria

Hi all, i would like to create a script that move and rename files from all the subdirectories of a given directory to others subdirectories of the same directory based on "matching" criteria in the "from" and "to" parameters. Example: Begin script from /home/test/1_T_2008* move to... (3 Replies)
Discussion started by: braidomik
3 Replies

9. AIX

Simultaneous searching for files (names matching certain criteria) in several directo

Hello everyone, My OS is AIX 5.2 I would like some help in getting command syntax that does the following: 1. Searches simultaneously several directories downward; 2. Checks every subdirectory in each directory (and so on...) for file names that contain certain characters such as “~”, start... (0 Replies)
Discussion started by: Hopeful
0 Replies

10. Shell Programming and Scripting

deleting files and folders matching criteria

Hello, I'm spendind hours trying to figure out how a script could remove files and folders older than 30days in a given volume (/dataVolumes/Booba.1.0). Within this volume, all users have their personal folder that starts with "RC-..", so the script should skip them for deletion. I will... (4 Replies)
Discussion started by: H3001
4 Replies
Login or Register to Ask a Question