Comment extraire des lignes par des mots dans une position spécifique, pas dans une colonne?

J'ai un file d'input comme celui-ci:

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 ^ 

Seules les lignes contiennent A à la position marquée sont ce dont j'ai besoin. Dans la plupart des lignes, A est un seul caractère comme une cinquième colonne comme la première ligne. Cependant, parfois, il est sur la quasortingème colonne comme la deuxième rangée, ou dans une string comme la dernière. Notez que A comme un seul caractère peut apparaître dans des positions autres que 22, mais je me soucie seulement quand il est ici.

J'ai besoin de ma sortie pour avoir seulement des lignes avec A , indépendamment de ce qu'il est en simple ou en 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 

Mais parfois, je ne veux extraire que des lignes avec un seul A , quelle que soit sa colonne:

 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 

Vous pouvez utiliser

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

si vous souhaitez inclure des cas comme A1023 , et

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

si vous ne voulez que des lignes où A apparaît comme un caractère isolé

NOTE: Dans le deuxième exemple, la notation \> correspondra à toutes les strings vides de fin.

extrait de la page man de grep

Le caractère barre oblique inverse et les expressions spéciales

Les symboles \< et \> correspondent respectivement à la string vide au début et à la fin d'un mot. Le symbole \b correspond à la string vide au bord d'un mot et \B correspond à la string vide à condition qu'il ne soit pas au bord d'un mot. Le symbole \w est un synonyme de [_[:alnum:]] et \W est un synonyme de [^_[:alnum:]] .

bash:

 while IFS= read -r line; do [[ ${line:21:2} == "A " ]] && echo "$line" done < file 
 > 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 

Un point que j'ai remarqué au sujet des données que vous décrivez est que votre A – quelle que soit sa position dans la colonne – est le dernier caractère alphabétique de la ligne. Cela signifie que nous pouvons l'aborder systématiquement comme ceci:

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

Cela ne renvoie que le A , mais si vous voulez que toute la ligne change le \1 en un & .

Avec 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 

Une autre command awk indépendamment de la position de 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 

Et les lignes qui consistent en 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