4

I have 2 files, one having 2 columns, another having 1 column.
The second file is sorted using sort -u.
Now the task is I need to join this column with the first column of the first file, which is not sorted.

So what will be the syntax? Will join -j 1 file2.txt sort -s -n -k 1 file1.txt work?

The output I want is actually the 2nd column of file 2 after joining and the unique entries in it.

File 2


1
2
3

File 1


2  500
1  5000 
1  300
3  3000 
3  300
4  450

Output


5000
300
500
3000
3
  • 2
    "Will this work?" Please try it out and check for yourself. I don't understand how your output could have four lines when file 1 only has three.
    – Mat
    Sep 28, 2012 at 8:30
  • Do you need to use File 2? Is sorting File 1 and then removing unwanted entries, e.g., lines with prefix >= 4 || duplicate values out of the question? Sep 28, 2012 at 8:30
  • Hello Mat, think like this: The second file is joined against the file 1 on column 1 and then the uniq entries are taken from column 2 of file 1. I tried but I think syntactically its not correct, thats what I was asking if its ok or not.
    – N. F.
    Sep 28, 2012 at 8:34

3 Answers 3

3

No need to use non-standard process substitution (<(...)) here:

sort file1 | join -o1.2 - file2 | uniq
2
  • This only works if file2 is already sorted. To really avoid the bashisms, the sorted files would need to be written to a temporary file.
    – jordanm
    Sep 28, 2012 at 15:10
  • @jordanm. file2 is sorted according to the OP's question. process substitution is a ksh feature originally, not a bashism. You don't need a temp file, you can use named or /dev/fd/n if supported as ksh/bash/zsh internally do for <(...). Sep 28, 2012 at 17:10
3
join file2.txt <(sort file1.txt) | awk '{print $2}'
0
2

One way using sort + awk. I sort the other file by its first number and in stable mode. In awk I compare what keys from file1 match with the keys of file2 and are not repeated, printing them:

sort -snk1,1 file1 | awk '
    FNR == NR { 
        keys[ $1 ] = 1; 
        next; 
    } 
    !values[ $2 ] && keys[ $1 ] { 
        printf "%s\n", $2; 
        values[ $2 ] = 1; 
    }
' file2 -

Output:

5000
300
500
3000

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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