2

I want to join two files according to number in the file, two number same file

Toyota   model1 
BMW      model2
Benz     model3
BMW      model4 
BMW      model5
Benz     model6 
Benz     model7

and second file

class C    model1
class E    model2
class A    model3
class W    model4
class W    model5
class C    model6
class A    model7

I want to join the two file according to the number, like this, joining each model number with each other in one file.

Toyota      class C  model1
BMW         class E  model2
Benz        class A  model3
BMW         class W  model4 
BMW         class W  model5  
Benz        Class C  model6
Benz        Class A  model7

after that delete the 'model' string

My code,

sort -V file1 > new_file1 
sort -V file2 > new_file2 
join newfile1 new_file2 > result.txt
sed 's/model[(1-9)]//g' result.txt > result_1.txt

the problem I'm getting an Error while joining the files

join: file1.txt:10: is not sorted: 03Benz   model   249
join: file2.txt:4: is not sorted: BMW   model   2

what if I want to count frequency after that

   ( this pair happen in the text 2 times) after joined 
Toyota      class C  1
BMW         class E  1
Benz        class A  2
BMW         class W  2
Benz        Class C  1
3
  • Thanks, two times I'm try to count how many pairs came together (car model and class) in my file Commented Mar 13, 2017 at 20:32
  • Sorry for that, I re-wrote it in more clear way Commented Mar 13, 2017 at 20:53
  • Are the columns in first and second file separated by spaces or by tabulators?
    – Cyrus
    Commented Mar 13, 2017 at 21:01

2 Answers 2

1

Use join.

It looks like changing the first space character in the file to something other than space will be sufficient to convert the file whitespace-delimited records.

Here's an implementation that replaces the first space with % and then joins on the second column of each file.

$ cat file2 | sed -e 's/ /%/' | join -1 2 -2 2 - file1

or

$ <file2 sed -e 's/ /%/' | join -1 2 -2 2 - file1

which produces

model1 class%C Toyota
model2 class%E BMW
model3 class%A Benz
model4 class%W BMW
model5 class%W BMW
model6 class%C Benz
model7 class%A Benz

If you need to convert it to a tab-delimited format, you can use tr.

tr ' %' '\t ' 
0

Join is the correct tool and you don't need any other conversion other than sorted files.

join -12 -23 -o 1.1 2.1 2.2 0 file1 file2 |column -t
Toyota  class  C  model1
BMW     class  E  model2
Benz    class  A  model3
BMW     class  W  model4
BMW     class  W  model5
Benz    class  C  model6
Benz    class  A  model7

Join is by default handling fields with space separation.
Option -12 means first file second field
Option -23 means second file third field
Option -o means format output:
1.1 = file1 field 1
2.1 = file2 field 1
0 = common /joined field

Apply LC_ALL=C in front of sort and join commands to ensure correct sorting and correct joining (i.e LC_ALL=C sort file)

About the counting part you can do something like this:

join -12 -23 -o 1.1 2.1 2.2 0 file1 file2 |cut -d' ' -f1-3 |sort |uniq -c
      1 BMW class E
      2 BMW class W
      2 Benz class A
      1 Benz class C
      1 Toyota class C

You can see both tests above online here.

1
  • @Lona Answer updated with counting part and online testing Commented Mar 14, 2017 at 0:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .