5

I have an input 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 contains A at the marked position are what I need. In most lines, A is a single character as a fifth column like the first line. However, sometimes it's on the fourth column like the second row, or in a string like the last one. Note that A as a single character can appear in positions other than 22, but I only care when it's here.

I need my output to have only lines with A, regardless it is in single or in string:

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 lines with single A, regardless its column:

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
7

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:]].

6

bash:

while IFS= read -r line; do 
    [[ ${line:21:2} == "A " ]] && echo "$line"
done < file
  • One of our master users just announced that he downvotes all bash read loops... ;-) – Hauke Laging May 29 '14 at 0:16
  • 2
    Upvoted on principle :) – jasonwryan May 29 '14 at 0:17
3
> 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
  • Thank you, it works. What if I only want to extract A, not Aabce? – Ooker May 29 '14 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 '14 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 '14 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 '14 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 '14 at 2:41
3

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 &.

2

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
2

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

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.