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 a file like this:

                     v
ATOM     57  O   LYS A   7       2.254  25.484  18.942  1.00 14.46
ATOM     77  NH1AARG A   8       5.557  19.204  13.388  0.55 24.50
TER    1648      ILE C 206
HETATM 1668  O   HOH A1023      25.873  38.343   2.138  1.00 21.99
                     ^

Only lines which has A at the marked position are what I need. You see, the A in the second row is on the fourth column, not fifth as others, and the fifth column of the last row is A1023, not A anymore.

I have tried this, but it needs some temp files, which I don't want to. I think there are tools for this.

I want to extract a whole line, not only the word.

I need my input to be:

ATOM     57  O   LYS A   7       2.254  25.484  18.942  1.00 14.46
ATOM     77  NH1AARG A   8       5.557  19.204  13.388  0.55 24.50
HETATM 1668  O   HOH A1023      25.873  38.343   2.138  1.00 21.99

But sometimes I also want to extract only A, not Aabcdef, like this:

ATOM     57  O   LYS A   7       2.254  25.484  18.942  1.00 14.46
ATOM     77  NH1AARG A   8       5.557  19.204  13.388  0.55 24.50
share|improve this question
add comment

6 Answers 6

up vote 6 down vote accepted

You can use

grep -E '^.{21}A' file

if you want to include cases like A1023, and

grep -E '^.{21}A\>' file

if you want only lines where A appears as an isolated character

NOTE: In the second example the notation \> will match any trailing empty strings.

excerpt from grep man page

The Backslash Character and Special Expressions

The symbols \< and \> respectively match the empty string at the beginning and end of a word. The symbol \b matches the empty string at the edge of a word, and \B matches the empty string provided it's not at the edge of a word. The symbol \w is a synonym for [_[:alnum:]] and \W is a synonym for [^_[:alnum:]].

share|improve this answer
    
Thank for your help. Actually there are many isolated A in other lines, but I only need when it appear in the 22nd position. After using your second code, man other lines still be extracted. –  Ooker May 29 at 0:24
1  
grep -E '^.{21}A' –  Hauke Laging May 29 at 0:27
    
Does it work now? –  steeldriver May 29 at 0:28
    
Thanks @HaukeLaging I just noticed that –  steeldriver May 29 at 0:30
    
It works now. Thank you –  Ooker May 29 at 0:37
add comment
> awk -v FS= '{ print $22 }' file
A
A
C
A

> awk -v FS= '$22=="A" { print; }' file
ATOM     57  O   LYS A   7       2.254  25.484  18.942  1.00 14.46
ATOM     77  NH1AARG A   8       5.557  19.204  13.388  0.55 24.50
HETATM 1668  O   HOH A1023      25.873  38.343   2.138  1.00 21.99
share|improve this answer
    
Thank you, it works. What if I only want to extract A, not Aabce? –  Ooker May 29 at 0:15
    
@Ooker I really don't understand the question as you can clearly see in the example that only "A" is "extracted"... Furthermore I have no idea what "Aabce" refers to. –  Hauke Laging May 29 at 0:18
    
Aabce is A1023 in the example. Say I want to extract only ` A ` in the 22nd position. There are others ` A ` in other places, but I don't want them. –  Ooker May 29 at 0:21
1  
@slm Wow... That's not obvious, you just have to know it: "If FS is the null string, then each individual character becomes a separate field." –  Hauke Laging May 29 at 1:49
1  
@slm I just remembered that statement from the man page. FS= was the second try (-F doesn't work). $22="A" means that you assign a value to $22, not that you check its value. Assigning a value leads to $0 being recomputed - with OFS between each two fields. –  Hauke Laging May 29 at 2:41
show 6 more comments

bash:

while IFS= read -r line; do 
    [[ ${line:21:2} == "A " ]] && echo "$line"
done < file
share|improve this answer
    
One of our master users just announced that he downvotes all bash read loops... ;-) –  Hauke Laging May 29 at 0:16
    
Upvoted on principle :) –  jasonwryan May 29 at 0:17
add comment

One point I've noticed about the data you describe is that your A - regardless of its column position - is the last alphabetic character on the line. That means we can address it systematically like this:

sed -n '\|.*\(A\)[ 0-9.]*$|s||\1|p'

That returns only the A, but if you want the whole line just change the \1 to an &.

share|improve this answer
add comment

With GNU grep:

$ grep -P '\bA\b' file
ATOM     57  O   LYS A   7       2.254  25.484  18.942  1.00 14.46
ATOM     77  NH1AARG A   8       5.557  19.204  13.388  0.55 24.50
share|improve this answer
add comment

Another awk command irrespective of position of A,

$ awk '$4~/A$/ || $5~/^A/' file
ATOM     57  O   LYS A   7       2.254  25.484  18.942  1.00 14.46
ATOM     77  NH1AARG A   8       5.557  19.204  13.388  0.55 24.50
HETATM 1668  O   HOH A1023      25.873  38.343   2.138  1.00 21.99

And the lines which consists of space A space,

$ awk '/ A /' file
ATOM     57  O   LYS A   7       2.254  25.484  18.942  1.00 14.46
ATOM     77  NH1AARG A   8       5.557  19.204  13.388  0.55 24.50
share|improve this answer
add comment

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.