0
votes

Un moyen plus rapide d'extraire des données de grand fichier

J'ai un fichier contenant environ 40000 cadres de coordonnées cartésiennes de 28 atomes. J'ai besoin d'extraire des coordonnées d'Atom 21 à 27 de chaque image.

J'ai essayé d'utiliser un script Bash avec une boucle pour la boucle. P> xxx pre>

Les données ont suivi: p >

28
-1373.82296 frame 0   xyz file generated by terachem
  Re       1.6345663991    0.9571586961    0.3920887712
   N       0.7107677071   -1.0248027788    0.5007181135
   N      -0.3626961076    1.1948218124   -0.4621264246
   C      -1.1299268126    0.0792071086   -0.5595954110
   C      -0.5157993503   -1.1509115191   -0.0469223696
   C       1.3354467762   -2.1017253883    1.0125736017
   C       0.7611763218   -3.3742177216    0.9821756556
   C      -1.1378354025   -2.4089069492   -0.1199253156
   C      -0.4944655989   -3.5108477831    0.4043826684
   C      -0.8597552614    2.3604180994   -0.9043060625
   C      -2.1340008843    2.4846545826   -1.4451933224
   C      -2.4023114639    0.1449111237   -1.0888703147
   C      -2.9292779079    1.3528434658   -1.5302429615
   H       2.3226814021   -1.9233467458    1.4602019023
   H       1.3128699342   -4.2076373780    1.3768411246
   H      -2.1105470176   -2.5059031902   -0.5582958817
   H      -0.9564415355   -4.4988963635    0.3544299401
   H      -0.1913951275    3.2219343258   -0.8231465989
   H      -2.4436044324    3.4620639189   -1.7693069306
   H      -3.0306593902   -0.7362803011   -1.1626515622
   H      -3.9523215784    1.4136948699   -1.9142814745
   C       3.3621999538    0.4972227756    1.1031860016
   O       4.3763020637    0.2022266109    1.5735343064
   C       2.2906331057    2.7428149541    0.0483795630
   O       2.6669163864    3.8206298898   -0.1683800650
   C       1.0351398442    1.4995168190    2.1137684156
   O       0.6510904387    1.8559680025    3.1601927094
  Cl       2.2433490373    0.2064711824   -1.9226174036


4 commentaires

Un exemple d'échantillon serait apprécié ...


Les numéros de cadre sont-ils dans le fichier dans la commande de tri?


Aussi d'autres commandes avec pour boucle prennent la mémoire aussi, si vous pouviez nous faire savoir exigence exacte, nous pourrions le faire dans un seul awk lui-même, comme indiqué par Jepessen gentiment Ajouter des échantillons dans votre message et laissez-nous savoir alors.


@Adam Sruut, veuillez poster des échantillons dans votre message non sous la forme d'images ou en tant que pièce jointe sur d'autres sites, veuillez le faire et laissez-nous savoir alors.


3 Réponses :


1
votes

Si les numéros de cadres dans le fichier sont déjà en ordre triés, par exemple. Ils ont des nombres 0 - 39999 dans cet ordre, alors peut-être que quelque chose aime cela pourrait faire le travail (non testé, puisque nous n'avons pas de fichier de saisie, comme le suggère de Jeppessen):

cat $1 | grep -A 27 -E "frame [0-9]+ " | \
awk '{if ($1 == "frame") n = 0; if (n++ > 20) print $2, $3, $4}' > new_coors.xyz


2 commentaires

En particulier puisque nous parlons d'efficacité ici, laissez tomber le chat dans votre solution. Un processus d'enfant moins à courir.


Je n'ai pas essayé de rendre ma solution efficace, mais plutôt de le rendre aussi semblable à SO SOI SI SE SI SELIER À COMPRENDER PAR OP. Vous avez raison sur Cat et Grep Regex pourrait également être intégré à AWK et, à la fin, la réponse pourrait ressembler à la réponse de Kvantour. Je opte pour un code propre plutôt que efficace, mais merci encore!



3
votes

La raison pour laquelle votre programme est lent, c'est que vous continuez à relire votre fichier d'entrée terminé et plus dans votre boucle. Vous pouvez tout faire avec la lecture de votre fichier un seul moment et utiliser AWK à la place:

awk '/frame/{fc++;c=0;next}{c++}(fc>=1000 && fc <=1500) && (c>20 && c<27){ print $2,$3,$4 }' input > output 


0 commentaires

0
votes

Vous pouvez peut-être utiliser 2 passes de grep code>, plutôt que des milliers de personnes?

En supposant que vous voulez les lignes 21-27 après chaque image et que vous ne voulez pas enregistrer le numéro de cadre lui-même. , la phrase suivante doit obtenir les lignes que vous voulez, que vous pouvez ensuite "ranger" avec awk: p> xxx pré>

si vous vouliez aussi les numéros de trame (je ne vois aucune preuve), Ou vous voulez vraiment restreindre la gamme de numéros de cadre, vous pouvez le faire avec TEE et> (Cadre Grep ') pour générer un deuxième fichier que vous auriez alors besoin de reprogrammer. Si vous avez ajouté -n à Grep, vous pouvez facilement fusionner de trier les fichiers sur le numéro de ligne. P>

Un autre moyen de restreindre le numéro de cadre sans faire de multiples passes serait une expression grep plus complexe qui décrit la gamme de nombres (-e parce que la vie est trop courte pour les backtsks): P>

-E ' frame (([0-9]{1,4}|[0-3][0-9]{1,4}) '


0 commentaires