J'ai un fichier au format suivant:
0.018029 15150000000 0.012615 15150000001 0.007046 15150000002 0.012989 15150000003
Je voudrais soustraire la colonne 1 lorsque la colonne 2 est la même. Par exemple pour le fichier d'entrée, je voudrais avoir quelque chose comme ceci:
0.019059000 15150000000 0.037088000 15150000000 0.035007000 15150000001 0.047622000 15150000001 0.053359000 15150000002 0.060405000 15150000002 0.068598000 15150000003 0.081587000 15150000003
Toutes les valeurs de la colonne 2 du fichier d'entrée vont par paires par exemple 15150000000 n'existe que deux fois, 15150000001 n'existe que deux fois etc.
Toute aide est plus que bienvenue!
3 Réponses :
awk
à la rescousse! (sans vérification d'erreur.)
$ awk 'function abs(x) {return x<0?-x:x} $2 in a {print abs($1-a[$2]),$2; delete a[$2]; next} {a[$2]=$1}' file
pour les enregistrements non triés mais encore une fois doublés pour la même clé
$ awk '$2 in a {print $1-a[$2],$2; delete a[$2]; next} {a[$2]=$1}' file 0.018029 15150000000 0.012615 15150000001 0.007046 15150000002 0.012989 15150000003
si la deuxième valeur n'est pas toujours supérieure à le premier et vous voulez la différence absolue
$ awk 'p==$2 {print $1-pv,p} {p=$2; pv=$1}' file 0.018029 15150000000 0.012615 15150000001 0.007046 15150000002 0.012989 15150000003
Merci beaucoup Karakfa! Il semble que cela fonctionne comme prévu! Une autre question rapide juste de la curiosité .. Cela ne semble pas fonctionner si le fichier n'est pas trié en premier en fonction de la colonne 2. Existe-t-il un moyen d'obtenir le même résultat même si le fichier n'est pas trié?
Que diriez-vous de
awk '{a[$2] = $1 - a[$2]} END {for (b in a) print a[b], b}' file
Ah, je vois que vous avez des valeurs en paires . Allez donc avec la réponse de Karakfa.
Un autre dans awk, soustrait le plus petit du plus grand:
0.007046 15150000002 0.018029 15150000000 0.012615 15150000001 0.012989 15150000003
Un exemple de sortie (en raison de shuf
randomness):
$ awk '{ if($2 in a) { # if another $2 already met print ((s=$1-a[$2])>0?s:-s),$2 # subtract smaller from bigger delete a[$2] # delete to save memory } else a[$2]=$1 # else store $2 }' <(shuf file) # shuf file to demo random order # replace with just the file name
vous pouvez remplacer a [$ 2] - $ 1
par -s
@karakfa Bon point, merci. C'est ce que fait une sieste trop longue à une personne ...: D.
Les mêmes valeurs dans la colonne 2 sont-elles toujours adjacentes?
pas nécessaire. Il peut sauter certaines valeurs. donc à partir de 15150000003, le suivant peut être 15150000004 ou 15150000005
Je veux dire dans le fichier, occupent-ils des lignes adjacentes?
oui, j'ai trié le fichier en fonction de la colonne 2.
Si le fichier n'est pas trié, soustrayez-vous le plus petit du plus grand ou le deuxième du premier ou quoi?
Oui si le fichier n'est pas trié, je voudrais ne pas avoir de valeurs négatives et soustraire le plus petit du plus grand puisque la première colonne représente le temps en secondes