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 have two files with few similar column one, two and third column with small variation and few other columns as follows.

file 1:

AT1  AT22  24  1 ATAGATA ATTATAT
AT2  AT24  22  0 ATAGATA ATTATAT
AT3  AT23  263 3 ATAGATA ATTATAT
AT4  AT28  252 6 ATAGATA ATTATAT

Similarly in file 2:

AT1  AT22  22  1 ATAGATA ATTATAT
AT3  AT23  265  1 ATAGATA ATTATAT
AT4  AT28  253  1 ATAGATA ATTATAT

The output should be Union and unique of these files with relaxation of +or -2 of the third column and if first three matches with these criteria, the fourth column has to be added from the both the files and other should be printed as usual which is like

AT1  AT22  24  2 ATAGATA ATTATAT
AT2  AT24  22  0 ATAGATA ATTATAT
AT3  AT23  263 4 ATAGATA ATTATAT
AT4  AT28  252 7 ATAGATA ATTATAT
share|improve this question

2 Answers 2

awk '
    NR==FNR {
        a[$1,$2] = $3
        val[$1,$2] = $4
        next
    } 
    ($1,$2) in a {
        for (n=$3-2; n<=$3+2; n++)
            if (a[$1,$2] == n) {
                $4+=val[$1,$2]
                break
            }
    } 
    {print}
' file2 file1
AT1 AT22 24 2 ATAGATA ATTATAT
AT2  AT24  22  0 ATAGATA ATTATAT
AT3 AT23 263 4 ATAGATA ATTATAT
AT4 AT28 252 7 ATAGATA ATTATAT
share|improve this answer
    
To make the columns look pretty, pipe the output through | column -t –  glenn jackman Mar 31 at 22:34
    
I was going through your solution only in stack overflow. stackoverflow.com/questions/17473972/…. But I couldn't rewrite the awk command to suit OP requirements. Can you please explain me the command? –  Ramesh Mar 31 at 22:35
    
Basically, I was trying to cat the 2 files and then use the approach that you had specified in the link that I provided :) –  Ramesh Mar 31 at 22:36
    
@glennjackman: I have tried the code and it worked well. But i am not able to find the line unique to single file in the output. This is able to print only the common lines in the two files. –  tarakaramji Apr 1 at 5:12

This should do what you asked (as far as my test cases work)

#!/bin/bash

# Concatenating the 2 files and sorting entries

SRC=`cat file1 file2 | sort `
FLAG="OFF"
i=1

while read a b c d e

do
 # Need an initial array to start comparing
 if [ "$i" -eq "1"  ];then
  init_vals=( "$a" "$b" "$c" "$d" "$e" )
  FLAG="ON"
 else
  # Start comparing
  vals=( "$a" "$b" "$c" "$d" "$e" )
  if [[ ${vals[0]} ==  "${init_vals[0]}" && ${vals[1]} == "${init_vals[1]}" ]]
   then
    # First and second column are identical, checking in delta on third meet the requirements
    delta=`expr ${vals[2]} - ${init_vals[2]}`
    if [ "$delta" -ge "-2" -a "$delta" -le "2" ]
    then
      # It does, adding values on column 4 and keeping other columns
      sum_col4=`expr ${vals[3]} + ${init_vals[3]}`
      vals=( "${init_vals[0]}" "${init_vals[1]}" "${init_vals[2]}" "$sum_col4" "${init_vals[4]}" )
      #This is a tracker, we don't print result until conditions are not met
      FLAG="ON"
    else
      #Delta on column 3 is not met
      FLAG="OFF"
    fi
  else
    #Column 1 and 2 are different
    FLAG="OFF"
  fi
#    echo "$FLAG"

   if [[ $FLAG != "ON" ]];then
     echo ${init_vals[@]}
     FLAG="ON"
   fi
   init_vals=( "${vals[@]}" )

 fi
 (( i++ ))
done <<< "$SRC"
#Printing last lastline
echo ${init_vals[@]}
share|improve this answer
    
That's without awk ^^ –  rMistero Mar 31 at 22:35
    
This shows a syntax error Syntax error: "(" unexpected (expecting "fi") @rMistero –  tarakaramji Apr 1 at 14:44
    
Strange, it works fine with bash version 4.2.25 –  rMistero Apr 1 at 18:02
    
I realised that I had missed some test cases, the new version does what you want –  rMistero Apr 1 at 18:02

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.