Print matches between two files and line after, while ordering by reference file

Viewed 94

I have a ref file

NP_001041718.1
XP_021405980.1
NP_001041719.1
XP_021385112.1
NP_001041721.1
XP_021394530.1
NP_001041722.1
XP_021394327.1
NP_001041723.1
XP_021400667.1

I need to capture the matches plus next line in a target file that looks like this, keeping the order from the reference file

NP_001041718.1
DVFMKGLSKAKEGVVAAAEKTKQGVAEAAGKTKEGVLYVGSRTKEGVVHGVTTVAEKTKEQVSNVGGAVVTGVTAVAQKTVEGAGNIAAATGLVKKDQLAKQNEEGFLQEGMVNNTGVAVDPENEAYEMPPEEEYQDYEPEA
NP_001041719.1
GKQNSKLRPEVMQDLLESTDFTEHEIQEWYKGFLRDCPSGHLSMEEFKKIYGNFFPYGDASKFAEHVFRTFDANGDGTIDFREFIIALSVTSRGKLEQKLKWAFSMYDLDGNGYISKSEMLEIVQAIYKMVSSVMKMPEDESTPEKRTEKIFRQMDTNRDGKLSLEEFIRGAKSDPSIVRLLQCDPSSAGQF
NP_001041721.1
TMESGAENQQSGDAAGTEAETQQMTVQAQPQIATLAQVSMPAAHATSSAPTVTLVQLPNGQTVQVHGVIQAAQPSVIQSPQVQTVQISTIAESEDSQESVDSVTDSQKRREILSRRPSYRKILNDLSSDAPGVPRIEEEKSEEETAAPAIATVTVPTPIYQTSSGQYIAITQGGAIQLSNNGTDGVQGLQTLTMTNAAATQPGTTILQYAQTTDGQQILVPSNQVVVQAASGDVQTYQIRTAPTSTIAPGVVMASSPALPTQPAEEAARKREVRLMKNREAARECRRKKKEYVKCLENRVAVLENQNKTLIEELKALKDLYCHKSD
NP_001041722.1
RVNESELNSSVLPRDPPAEGAPRRQPWVTSTLAAILIFTIAVDLLGNLLVILSVYRNKKLRNAGNVFVVSLAVADLIVAIYPYPLVLTSVFHNGWKLGYLHCQISGFLMGLSVIGSIFNITGIAINRYCYICHSLKYDKLYSDRNSLCYIVLIWLLTFVAIVPNLFVGSLQYDPRIYSCTFAQSVSSAYTIAVVFFHFLLPIAVVTFCYLRIWILVIQVRRRVKPDNNPRLKPHDFRNFVTMFVVFVLFAVCWAPLNFIGIAVAVNPKTVIPRIPEWLFVSSYYMAYFNSCLNAIVYGLLNQNFRREYKRIIVNFCTAKVFFQDSSNDAGDRMRSKPSPLITNNNQVKVDSV
NP_001041723.1
LENGSLRNCCDPGGRGRLGLAEREAAAAGAPRPAWVVPVLSSVLIFTTVVDILGNLLVILSVFKNRKLRNSGNAFVVSLALADLVVALYPYPLVLLAIFHNGWTLGETHCKASGFVMGLSVIGSIFNITAIAINRYCYICHSFAYDKVYSCWNTMLYVSLVWILTVIATVPNFFVGSLKYDPRIYSCTFVQTASSYYTIAVVVIHFIVPITIVSFCYLRIWVLVLQVRRRVKSETKPRLKPSDFRNFLTMFVVFVIFAFCWAPLNFIGLAVAIDPTEMAPKVPEWLFIISYLMAYFNSCLNAIIYGLLNQNFRNEYKRISMSLWMPRLFFQDTSKGGTDGQKSKPSPALNNNNQMKTETL
XP_021405980.1
DVFMKGLSKAKEGVVAAAEKTKQGVAEAAGKTKEGVLYVGSRTKEGVVHGVTTVAEKTKEQVSNVGGAVVTGVTAVAQKTVEGAGNIAAATGLVKKDQLAKQNEEGFLQEGMVNNTGVAVGPENEAYKMPPEEEYQDYEPEA
XP_021385112.1
GKQNSKLRPEVMQDLLESTDFTEHEIQEWYKGFLRDCPSGHLSMEEFKKIYGNFFPYGDASKFAEHVFRTFDANGDGTIDFREFIIALSVTSRGKLEQKLKWAFSMYDLDGNGYISKSEMLEIVQAIYKMVSSVMKMPEDESTPEKRTEKIFRQMDTNRDGKLSLEEFIRGAKSDPSIVRLLQCDPSSAGQF
XP_021394530.1
TMESGAENQQSGDAAGTEAETQQMTVQAQPQIATLAQVSMPAAHATSSAPTVTLVQLPNGQTVQVHGVIQAAQPSVIQSPQVQTVQISTIAESEDSQESVDSVTDSQKRREILSRRPSYRKILNDLSSDAPGVPRIEEEKSEEETAAPAIATVTVPTPIYQTSSGQYIAITQGGAIQLSNNGTDGVQGLQTLTMTNAAATQPGTTILQYAQTTDGQQILVPSNQVVVQAASGDVQTYQIRTAPTSTIAPGVVMASSPALPTQPAEEAARKREVRLMKNREAARECRRKKKEYVKCLENRVAVLENQNKTLIEELKALKDLYCHKSD
XP_021394327.1
RVNESELNSSVLPRDPPAEGAPRRQPWVTSTLAAILIFTIAVDLLGNLLVILSVYRNKKLRNAGNVFVVSLAVADLIVAIYPYPLVLTSVFHNGWKLGYLHCQISGFLMGLSVIGSIFNITGIAINRYCYICHSLKYDKLYSDRNSLCYIVLIWLLTFVAIVPNLFVGSLQYDPRIYSCTFAQSVSSAYTIAVVFFHFLLPIAVVTFCYLRIWILVIQVRRRVKPDNNPRLKPHDFRNFVTMFVVFVLFAVCWAPLNFIGIAVAVNPKTVIPRIPEWLFVSSYYMAYFNSCLNAIVYGLLNQNFRREYKRIIVNFCTAKVFFQDSSNDAGDRMRSKPSPLITNNNQVKVDSV
XP_021400667.1
LENGSLRNCCDPGGRGRLGLAEREAAAAGAPRPAWVVPVLSSVLIFTTVVDILGNLLVILSVFKNRKLRNSGNAFVVSLALADLVVALYPYPLVLLAIFHNGWTLGETHCKASGFVMGLSVIGSIFNITAIAINRYCYICHSFAYDKVYSCWNTMLYVSLVWILTVIATVPNFFVGSLKYDPRIYSCTFVQTASSYYTIAVVVIHFIVPITIVSFCYLRIWVLVLQVRRRVKSETKPRLKPSDFRNFLTMFVVFVIFAFCWAPLNFIGLAVAIDPTEMAPKVPEWLFIISYLMAYFNSCLNAIIYGLLNQNFRNEYKRILMSLWMPRLFFQDTSKGGTDGQKSKPSPALNNNNQMKTETI

so the output would look like

    NP_001041718.1
    DVFMKGLSKAKEGVVAAAEKTKQGVAEAAGKTKEGVLYVGSRTKEGVVHGVTTVAEKTKEQVSNVGGAVVTGVTAVAQKTVEGAGNIAAATGLVKKDQLAKQNEEGFLQEGMVNNTGVAVDPENEAYEMPPEEEYQDYEPEA
    XP_021405980.1
    DVFMKGLSKAKEGVVAAAEKTKQGVAEAAGKTKEGVLYVGSRTKEGVVHGVTTVAEKTKEQVSNVGGAVVTGVTAVAQKTVEGAGNIAAATGLVKKDQLAKQNEEGFLQEGMVNNTGVAVGPENEAYKMPPEEEYQDYEPEA
    NP_001041719.1
    GKQNSKLRPEVMQDLLESTDFTEHEIQEWYKGFLRDCPSGHLSMEEFKKIYGNFFPYGDASKFAEHVFRTFDANGDGTIDFREFIIALSVTSRGKLEQKLKWAFSMYDLDGNGYISKSEMLEIVQAIYKMVSSVMKMPEDESTPEKRTEKIFRQMDTNRDGKLSLEEFIRGAKSDPSIVRLLQCDPSSAGQF
    XP_021385112.1
    ....

I know how to find the matches in target while keeping the order from ref awk 'FNR==NR {a[$1]=$0; next}; $1 in a {getline} {print a[$1]}' target ref , but I don't know how to print the line after. I know how to print the line after with grep -A 1 -f ref target, but it reorders the target file

3 Answers

Would you please try the following:

awk 'FNR==NR {                          # process "target" file
    if (FNR%2) a[key=$1]=$0             # store odd lines in array a
    else b[key]=$0                      # store even lines in array b using the same key as the previous line
    next
}
$1 in a {print a[$1]; print b[$1]}      # if the key matches, print the odd line and the even line
' target ref

With your shown samples, please try following awk code. Written and tested in GNU awk.

awk '
FNR==NR{
  if(FNR%2==0){
    arr[prev]=$0
  }
  else{
    prev=$0
  }
  next
}
($0 in arr){
  print $0 ORS arr[$0]
}
' target ref

Explanation: Adding detailed explanation for above.

awk '                     ##Starting awk program from here.
FNR==NR{                  ##Checking condition if FNR==NR which will be TRUE when target file is being read.
  if(FNR%2==0){           ##Checking condition if current line is getting divided completely by 0 then do following.
    arr[prev]=$0          ##Creating arr with index of prev and value is current line.
  }
  else{                   ##Else do following.
    prev=$0               ##Setting prev to current line.
  }
  next                    ##next will skip all further statements from here.
}
($0 in arr){              ##If current line is present in arr then do following.
  print $0 ORS arr[$0]    ##Printing current line ORS and arr with index of $0.
}
' target ref              ##Mentioning Input_file names here.

You could reverse the order of the files passed to awk passing the ref file first and create an array with an incremented number to keep the order for the key and the value.

Instead of using getline, you can save the last line in a variable, the check if the current line is present in the array where the values of the first file are stored as the key.

If it is, then store the last line plus the current in a new array final for example, and loop that array in the END block.

awk '{
  if (FNR==NR) {
    a[$1]=i++; next
  }
  if (last in a) {
    final[a[last]] = last RS $1
  }
  last = $1
}
END { for (i in final) print final[i] }
' ref target

Output

NP_001041718.1
DVFMKGLSKAKEGVVAAAEKTKQGVAEAAGKTKEGVLYVGSRTKEGVVHGVTTVAEKTKEQVSNVGGAVVTGVTAVAQKTVEGAGNIAAATGLVKKDQLAKQNEEGFLQEGMVNNTGVAVDPENEAYEMPPEEEYQDYEPEA
XP_021405980.1
DVFMKGLSKAKEGVVAAAEKTKQGVAEAAGKTKEGVLYVGSRTKEGVVHGVTTVAEKTKEQVSNVGGAVVTGVTAVAQKTVEGAGNIAAATGLVKKDQLAKQNEEGFLQEGMVNNTGVAVGPENEAYKMPPEEEYQDYEPEA
NP_001041719.1
GKQNSKLRPEVMQDLLESTDFTEHEIQEWYKGFLRDCPSGHLSMEEFKKIYGNFFPYGDASKFAEHVFRTFDANGDGTIDFREFIIALSVTSRGKLEQKLKWAFSMYDLDGNGYISKSEMLEIVQAIYKMVSSVMKMPEDESTPEKRTEKIFRQMDTNRDGKLSLEEFIRGAKSDPSIVRLLQCDPSSAGQF
XP_021385112.1
GKQNSKLRPEVMQDLLESTDFTEHEIQEWYKGFLRDCPSGHLSMEEFKKIYGNFFPYGDASKFAEHVFRTFDANGDGTIDFREFIIALSVTSRGKLEQKLKWAFSMYDLDGNGYISKSEMLEIVQAIYKMVSSVMKMPEDESTPEKRTEKIFRQMDTNRDGKLSLEEFIRGAKSDPSIVRLLQCDPSSAGQF
NP_001041721.1
TMESGAENQQSGDAAGTEAETQQMTVQAQPQIATLAQVSMPAAHATSSAPTVTLVQLPNGQTVQVHGVIQAAQPSVIQSPQVQTVQISTIAESEDSQESVDSVTDSQKRREILSRRPSYRKILNDLSSDAPGVPRIEEEKSEEETAAPAIATVTVPTPIYQTSSGQYIAITQGGAIQLSNNGTDGVQGLQTLTMTNAAATQPGTTILQYAQTTDGQQILVPSNQVVVQAASGDVQTYQIRTAPTSTIAPGVVMASSPALPTQPAEEAARKREVRLMKNREAARECRRKKKEYVKCLENRVAVLENQNKTLIEELKALKDLYCHKSD
XP_021394530.1
TMESGAENQQSGDAAGTEAETQQMTVQAQPQIATLAQVSMPAAHATSSAPTVTLVQLPNGQTVQVHGVIQAAQPSVIQSPQVQTVQISTIAESEDSQESVDSVTDSQKRREILSRRPSYRKILNDLSSDAPGVPRIEEEKSEEETAAPAIATVTVPTPIYQTSSGQYIAITQGGAIQLSNNGTDGVQGLQTLTMTNAAATQPGTTILQYAQTTDGQQILVPSNQVVVQAASGDVQTYQIRTAPTSTIAPGVVMASSPALPTQPAEEAARKREVRLMKNREAARECRRKKKEYVKCLENRVAVLENQNKTLIEELKALKDLYCHKSD
NP_001041722.1
RVNESELNSSVLPRDPPAEGAPRRQPWVTSTLAAILIFTIAVDLLGNLLVILSVYRNKKLRNAGNVFVVSLAVADLIVAIYPYPLVLTSVFHNGWKLGYLHCQISGFLMGLSVIGSIFNITGIAINRYCYICHSLKYDKLYSDRNSLCYIVLIWLLTFVAIVPNLFVGSLQYDPRIYSCTFAQSVSSAYTIAVVFFHFLLPIAVVTFCYLRIWILVIQVRRRVKPDNNPRLKPHDFRNFVTMFVVFVLFAVCWAPLNFIGIAVAVNPKTVIPRIPEWLFVSSYYMAYFNSCLNAIVYGLLNQNFRREYKRIIVNFCTAKVFFQDSSNDAGDRMRSKPSPLITNNNQVKVDSV
XP_021394327.1
RVNESELNSSVLPRDPPAEGAPRRQPWVTSTLAAILIFTIAVDLLGNLLVILSVYRNKKLRNAGNVFVVSLAVADLIVAIYPYPLVLTSVFHNGWKLGYLHCQISGFLMGLSVIGSIFNITGIAINRYCYICHSLKYDKLYSDRNSLCYIVLIWLLTFVAIVPNLFVGSLQYDPRIYSCTFAQSVSSAYTIAVVFFHFLLPIAVVTFCYLRIWILVIQVRRRVKPDNNPRLKPHDFRNFVTMFVVFVLFAVCWAPLNFIGIAVAVNPKTVIPRIPEWLFVSSYYMAYFNSCLNAIVYGLLNQNFRREYKRIIVNFCTAKVFFQDSSNDAGDRMRSKPSPLITNNNQVKVDSV
NP_001041723.1
LENGSLRNCCDPGGRGRLGLAEREAAAAGAPRPAWVVPVLSSVLIFTTVVDILGNLLVILSVFKNRKLRNSGNAFVVSLALADLVVALYPYPLVLLAIFHNGWTLGETHCKASGFVMGLSVIGSIFNITAIAINRYCYICHSFAYDKVYSCWNTMLYVSLVWILTVIATVPNFFVGSLKYDPRIYSCTFVQTASSYYTIAVVVIHFIVPITIVSFCYLRIWVLVLQVRRRVKSETKPRLKPSDFRNFLTMFVVFVIFAFCWAPLNFIGLAVAIDPTEMAPKVPEWLFIISYLMAYFNSCLNAIIYGLLNQNFRNEYKRISMSLWMPRLFFQDTSKGGTDGQKSKPSPALNNNNQMKTETL
XP_021400667.1
LENGSLRNCCDPGGRGRLGLAEREAAAAGAPRPAWVVPVLSSVLIFTTVVDILGNLLVILSVFKNRKLRNSGNAFVVSLALADLVVALYPYPLVLLAIFHNGWTLGETHCKASGFVMGLSVIGSIFNITAIAINRYCYICHSFAYDKVYSCWNTMLYVSLVWILTVIATVPNFFVGSLKYDPRIYSCTFVQTASSYYTIAVVVIHFIVPITIVSFCYLRIWVLVLQVRRRVKSETKPRLKPSDFRNFLTMFVVFVIFAFCWAPLNFIGLAVAIDPTEMAPKVPEWLFIISYLMAYFNSCLNAIIYGLLNQNFRNEYKRILMSLWMPRLFFQDTSKGGTDGQKSKPSPALNNNNQMKTETI

A variation using getline into a variable:

awk '{
  if (FNR==NR) {
    i++;a[i]=$1;b[$1]=i;next
  }
  if ($1 in b && (getline tmp) > 0) {
    final[b[$1]] = a[b[$1]] RS tmp
  }
}
END { for (i in final) print final[i] }
' ref target
Related