J'ai un fichier de données que je souhaite normaliser à l'aide awk
du dernier point de données. Pour cela, je voudrais d'abord accéder au dernier point de données, normaliser les données, puis traiter normalement.
La méthode suivante, utilisant tac
deux fois, fait le travail, mais est peut-être plus compliquée que nécessaire.
$ cat file
0 5
1 2
2 3
3 4
$ tac file | awk 'NR==1{norm=$2} {print $1, $2/norm}' | tac
0 1.25
1 0.5
2 0.75
3 1
Ma question est la suivante: est-il possible d'obtenir le résultat ci-dessus en utilisant uniquement awk?
Je pense que la réponse est "Non, awk scanne le fichier ligne par ligne", mais je suis ouvert aux suggestions d'alternatives.
la source
$ awk --version GNU Awk 3.1.8
. Pouvez-vous peut-être ajouter une très petite explication sur la façon dont deux fichiers d'entrée sont traités et quenext
fait-on?Si votre source de données est un fichier qui peut être lu plusieurs fois (c'est-à-dire qu'il ne s'agit pas d'un flux), vous devez d'abord utiliser
tail(1)
pour obtenir les données que vous souhaitez à partir de la dernière ligne et les transmettre à awk pour son traitement séquentiel du fichier.tail
cherchera à la fin du fichier pour lire la dernière ligne sans avoir besoin de lire toutes les données avant lui.Ce sera une grande victoire sur les gros fichiers où le fichier entier ne rentrera pas dans le cache du tampon (ce qui signifie qu'il devra être lu deux fois sur le disque, une fois pour chaque passage), et aidera dans une moindre mesure en n'ayant pas besoin de scanner l'entrée pour arriver à la dernière ligne. Les fichiers plus petits peuvent ne pas montrer beaucoup de différence avec une approche en deux passes.
la source
Vous pouvez les charger dans un tableau et les lire à l'envers:
Vous pourriez le faire plus efficacement, mais ce genre d'illustration illustre pourquoi ce
awk
n'est pas le bon outil pour cela. Continuez à utiliser letac
cas échéant, GNU tac est généralement le plus rapide parmi une variété d'outils pour ce travail.la source
for
-loopsawk
n'est pas la solution.