Remove fields in file A that don't contain matches in file B, line by line

Viewed 61

I have a series of paired files, tab separated.

I want to compare line by line each pair and keep in file B only the fields that contain a match with the paired file A.

Example file A:

a b
d c

Example file B:

f>543 h<456 b>536 d>834 v<75345 a>12343
t>4562 c>623 f>3246 h>1345 d<52312

Desired output:

b>536 a>12343
c>623 d<52312

So far I have tried:

  1. Convert files B in one-liner files: cat file B | sed 's/\t/\n/g' > file B.mod

  2. Grep one string in file A from file B, print the matching line and the next line, convert the output from 2 line back to single tab separated line:

cat file B.mod | grep -A1 (string) | awk '{printf "%s%s",$0,NR%2?"\t":"\n" ; }'

...but this failed since I realized that the matches can be in different order in A and B, as in the example above.

I'd appreciate some help as this goes far beyond my bash skills.

1 Answers

With your shown samples, please try following awk code.

awk '
FNR==NR{
  for(i=1;i<=NF;i++){
    arr[FNR,$i]
  }
  next
}
{
  val=""
  for(i=1;i<=NF;i++){
    if((FNR,substr($i,1,1)) in arr){
      val=(val?val OFS:"")$i
    }
  }
  print val
}
'  filea  fileb

Explanation: Adding detailed explanation for above.

awk '                         ##Starting awk Program from here.
FNR==NR{                      ##Checking condition FNR==NR which will be true when filea is being read.
  for(i=1;i<=NF;i++){         ##Traversing through all fields here.
    arr[FNR,$i]               ##Creating array with index of FNR,current field value here.
  }
  next                        ##next will skip all further statements from here.
}
{
  val=""                      ##Nullify val here.
  for(i=1;i<=NF;i++){         ##Traversing through all fields here.
    if((FNR,substr($i,1,1)) in arr){ ##checking condition if 1st letter of each field with FNR is present in arr then do following.
      val=(val?val OFS:"")$i  ##Creating val which has current $i value in it and keep adding values per line here.
    }
  }
  print val                   ##Printing val here.
}
'  filea  fileb               ##Mentioning Input_file names here.
Related