Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to write a shell script that get two files A and B, and get a result like this:

File A:

user_a tel_a addr_a
user_b tel_b addr_b

File B:

process_1 user_a
process_2 user_a
process_3 user_b

And the result:

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

How can i do this? awk or something else?

share|improve this question
2  
I think it can be done using cut and paste only, but I do not get the synthax right. –  Bernhard Feb 26 '12 at 18:55
    
My files have many records and fields, i can't cut and paste!! This is just a sample. –  Navid Farhadi Feb 26 '12 at 18:58
1  
@NavidFarhadi not cut&paste: there are two actual command cut and paste look at their manual page. –  Matteo Feb 26 '12 at 19:07
    
I can load both files in memory completely and i can also use awk. –  Navid Farhadi Feb 26 '12 at 19:21
    
I also can use perl or others, if they were executable in linux command line. –  Navid Farhadi Feb 26 '12 at 19:28
add comment

2 Answers

up vote 13 down vote accepted

join ...

join -1 2 -2 1 FileB FileA

Output

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

The input files need to be sorted by the key field ... Your example files are already sorted, so there was no need, but otherwise you could incorporate the sort as follows.

join -1 2 -2 1 <(sort -k2 FileB) <(sort FileA)
share|improve this answer
    
What means the number parameters? –  Navid Farhadi Feb 26 '12 at 19:31
4  
@Navid: You can always get the best and most accurate description of a command's paramaters by refering to the manual, by typing man join into the terminal's command-line... -1 2   -2 1 means: join on the '1st-file 2nd-field' and the '2nd-file 1st-field' –  Peter.O Feb 26 '12 at 19:44
add comment

Since join and paste aren't available everywhere (they're not on my BusyBox-based system, for example), here is how to do it with awk, as requested:

awk 'BEGIN {
    while( (getline < "fileA") > 0) A[$1]=$2 OFS $3 # read fileA into the array A
    close("fileA")
  } {
    print $2, $1, A[$2]
  }' fileB
share|improve this answer
    
BTW you missed the seperator A[$1]=$2 OFS $3 ... Here is another variant which avoids the manual loop in BEGIN, but it's pretty much the same (to awk), although it does introduce an otherwise unnecessary condition test for the second file: awk 'NR==FNR {A[$1]=$2 OFS $3;next} {print $2, $1, A[$2]}' fileA fileB ...(+1) –  Peter.O Apr 19 '12 at 23:13
    
Thanks, added the forgotten OFS. –  dubiousjim Apr 19 '12 at 23:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.