I am currently working with a file for atomic distances in a protein. Distances are either within the same residue or between different residues. I am wondering if there is a way to sort/find all of the lines that contain distances in the same residue, so that I can easily copy these lines into a new file to work with separately. An example of the file is shown below, both for a distance within the same residue (164), and one with a distance between different residues (38, 124).

With sample input of:

assign (resid 164 and name CD ) (resid 164 and name CE ) 4.6 2.6 2.6 ! 
assign (resid 38 and name CE* ) (resid 124 and name CA ) 4.6 2.6 2.6 ! 

... the output should be:

assign (resid 164 and name CD ) (resid 164 and name CE ) 4.6 2.6 2.6 ! 

because the residues are the same between the two entries.

  • Not knowing enough about the subject matter, can you explain more why "resid 164 and name CD" matches "resid 164 and name CE", and also why "resid 38 and name CE*" matches "resid 124 and name CA"? Nothing about the second line jumps out to me as matching, and in the first line I expected "CD" to match "CE". – Jeff Schaller Jun 25 at 17:09
  • This is specifically used for protein structure calculation; atomic distances are sorted based on intra-residue vs. inter-residue. Intraresidue distance restraints have different distance criteria. (resid 164 and name CD) (resid 164 and name CE) means a distance between two different carbon atoms (CD and CE) in the same residue, 164. The second example is a distance between CE of residue 38 and CA of residue 124, which should not match. I was using the two different examples to illustrate that I want to separate matches and move to a different file – user359525 Jun 25 at 17:27
  • Ahhh, I misunderstood those two lines as what you're looking for; they're instead sample input? And you'd want only the first line back, because 164 exists as the same residue? – Jeff Schaller Jun 25 at 17:28
  • Yes, this is exactly it – user359525 Jun 25 at 17:29
  • Thank you; I've edited your question to reflect the new understanding, so that people don't have to read through comments to sort it out. Please further edit if I've mis-stated your intentions! – Jeff Schaller Jun 25 at 17:31

To match the same pattern twice in one line, you can use a backreference to a capture group


grep -E '(resid [0-9]+ ).*\1'


grep -E 'resid ([0-9]+ ).*resid \1'
  • 1
    Watch out for a partial match on the backref, e.g. resid 12 should not match resid 123. Adding a space after the backref in the second approach should do the job. – ottomeister Jun 25 at 17:23
  • @ottomeister thanks - good catch – steeldriver Jun 25 at 17:28
awk '$3 == $9' yourfile

should show the lines that have matching residues. Change == to != to get the lines that have non-matching residues.


Cheekily extending @ottomeister code to include grouping the output to specific files

awk '{if ($3 <= $9) {print $0 >> $3"."$9".resid"} else { print $0 >> $9"."$3".resid"}}' data

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.