I have a .txt file with multiple lines that gives amino acid and residue data. The data looks like this:

ARG262-Side ASP368-Side 140,83%
ARG95-Side GLU107-Side 103,73%
ARG474-Side VAL468-Main 94,93%
PHE169-Main ALA190-Main 94,63%
THR205-Side ASP203-Side 94,07%
ILE299-Main LYS249-Main 94%
LEU354-Main LYS365-Main 93,6%
ARG346-Side GLU263-Side 93,57%
LEU301-Main ALA247-Main 93,43%
ALA190-Main PHE169-Main 93,37%
SER252-Side ASP296-Side 93,1%
TYR424-Side ASN446-Main 93%

I can roughly say that the numbers indicate residues and the letters indicate aminoacids. So, both in the first and second field of each line, the part before the - consists of an aminoacid identifier and a residue value. I want to print only lines where the see residue value lies in a certain range, regardless of amino acid, and regardless of whether the first or second field matches the criterion.

For example, from the above input file, I want to extract data that contains only residues between 300-425. In this case, my output should look like this:

ARG262-Side ASP368-Side 140,83%
LEU354-Main LYS365-Main 93,6%
ARG346-Side GLU263-Side 93,57%
LEU301-Main ALA247-Main 93,43%
TYR424-Side ASN446-Main 93%

I tried using the grep command for this, but I wasn't very successful. Is there a command I can use other than grep?

  • 2
    Please edit your question and include what you already tried, so that answerers don't suggest the same commands. – Panki Mar 8 at 14:30
  • you could say that specific field info; genome.jp/kegg/catalog/codes1.html – αғsнιη Mar 8 at 14:46
  • A general remark to notice: If you deal with files on Linux that have been created/modified on a Windows machine, be aware that these OSs use different end-of-line indicators. If you experience unexpected output behaviour, you may have to run the file through dos2unix before processing. – AdminBee Mar 8 at 15:49
  • Actually, I downloaded the Ubuntu console to my computer and working on Windows. But if I switch to Linux completely in the future, I will keep this in mind. Thank you so much @AdminBee. :) – Derman Basturk Mar 8 at 15:59

Tools that mainly deal with regular expressions are notoriously bad at dealing with numbers. In this case, I would suggest using something like awk instead of grep:

$ awk '{ r1 = substr($1,4,3); r2 = substr($2,4,3) } (r1 >= 300 && r1 <= 425) || (r2 >= 300 && r2 <= 425)' file
ARG262-Side ASP368-Side 140,83%
LEU354-Main LYS365-Main 93,6%
ARG346-Side GLU263-Side 93,57%
LEU301-Main ALA247-Main 93,43%
TYR424-Side ASN446-Main 93%

The awk code extracts the tree characters, starting at offset four, from the first two whitespace-delimited fields on each line, and calls these r1 and r2. I'm using substr() to extract the numbers at fixed positions in the data of the fields, but you could also just delete all non-digits, if you're certain that the only digits are the ones that you're interested in. You would do that with

r1 = $1; gsub("[^[:digit:]]", "", r1)

and similarly for r2 using $2.

If the condition at the end is true, the current line would be printed.

  • Thank you so much, it worked. But I do not fully understand what the parameters you give to r values mean. r1 = substr ($ 1,4,3); r2 = substr ($ 2,4,3) Would you please explain it a little bit more? – Derman Basturk Mar 8 at 15:35
  • The substr() command extracts a part of the string mentioned as first argument, starting at the character nr. stated in the second argument, and with a length as per the third argument. So, r1 = substr($1, 4, 3) assigns to r1 that part of the first field ($1) that starts at the 4th character (the first digit) and is three characters (=digits in this case) long. Try man awk, it is should be well-documented. – AdminBee Mar 8 at 15:46
  • I got it now, thank you very much. :) – Derman Basturk Mar 8 at 15:52
  • Hello again. I tried to run this code: $ awk '{ r1 = substr($1,4,3); r2 = substr($2,4,3) } (r1 >= 206 && r1 <= 212 || (r2 >= 206 && r2 <= 212)' deneme.dat But I got an error like this: awk: cmd. line:2: { r1 = substr($1,4,3); r2 = substr($2,4,3) } (r1 >= 206 && r1 <= 212 || (r2 >= 206 && r2 <= 212) awk: cmd. line:2: ^ unexpected newline or end of string I checked my file but could not find what caused the error. Do you have any idea? – Derman Basturk Mar 9 at 9:17
  • @DermanBasturk Yes, you seem to be missing a ), just before ||. – Kusalananda Mar 9 at 9:18

Using awk:

awk -F'(^| )...|-' '$2>300 && $2<425 || $4>300 && $4<425' infile

here, we set the field seperator to:

  • start of line followed by 3 characters ^..., or
  • a space followed by 3 characters ..., or
  • a hyphen character

then based on these, column#2 and column#4 would be the residues of the aminoacids and so we checks if that's between given range.

  • 1
    You could also use [^[:digit:]]+ as FS and check $2 and $3. – Kusalananda Mar 8 at 14:56
  • @Kusalananda ah, yes, that's good one and assuming there is no any digits after - in first column then it will mess and some would be in $2 and $3 and some in $2 and $4. – αғsнιη Mar 8 at 15:09

Try this:

grep -E '[^0-9](3[0-9][0-9]|4[01][0-9]|42[0-5])-' file`
  • -E enables extended regular expressions (where you don't need to backslash parentheses and pipe)
  • [^0-9]( -- a non-digit, followed by
    • 3[0-9][0-9]| a number between 300 and 399, or
    • 4[01][0-9]| a number between 400 and 419, or
    • 42[0-5] a number between 420 and 425
  • )- followed by a hyphen

Providing the non-digit requirement means you don't match ABC1234-Something

grep -E "(^[[:upper:]]{3}(3[0-9]{2}|4([0-1][0-9]|2[0-5]))|\b[[:upper:]]{3}(3[0-9]{2}|4([0-1][0-9]|2[0-5])))" sample.txt

grep -E with extended regular expression.

^[[:upper:]]{3} : If the line start with three upper alphabetic character

3[0-9]{2} : Match any sequence of digit greater or equal to 300

| : or

4([0-1][0-9]|2[0-5]) : between 400 and 425.

| : Or (here look at the second column)

\b : The world is boundaries (There is a space)

[[:upper:]]{3}(3[0-9]{2}|4([0-1][0-9]|2[0-5])) : The same as in the first path.

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.