Grep reste de la ligne… après le match

8

J'ai un fichier contenant seulement deux lignes, avec la structure suivante:

$ cat /tmp/pwpower.log
000D6F0000D34227, -114.10
000D6F0001A405C4, -130.09

Les valeurs sont les valeurs de puissance de ma centrale solaire. Une valeur négative signifie une génération.

J'aurais besoin des valeurs extraites via grep / sed / awk - quelle que soit la manière la plus intelligente. J'ai besoin d'extraire les deux valeurs séparément et sans le signe moins.

Ce que je fais maintenant est un peu stupide mais cela fonctionne - je suis sûr que beaucoup d'entre vous auront des moyens plus intelligents pour moi :-) Ici, bien sûr, je ne vois que les valeurs plus Minus.

Pour obtenir la première valeur:

cat /tmp/pwpower.log |grep -o "\-.*" | head -n 1

Pour obtenir la deuxième valeur:

cat /tmp/pwpower.log |grep -o "\-.*" | tail -n1

Et question connexe, existe-t-il un moyen simple de prendre ces chaînes et de les transformer pour que je puisse calculer la somme?

njordan
la source

Réponses:

12

Toutes les valeurs:

$ awk -F '[ -]*' '$0=$NF' /tmp/pwpower.log
114.10
130.09

Valeur en première ligne:

$ awk -F '[ -]*' 'NR==1{print $NF;exit}' /tmp/pwpower.log
114.10

Valeur en deuxième ligne:

$ awk -F '[ -]*' 'NR==2{print $NF;exit}' /tmp/pwpower.log
130.09

Somme de toutes les valeurs:

$ awk -F '[ -]*' '{sum+=$NF} END{print sum}' /tmp/pwpower.log
244.19
Adrian Frühwirth
la source
1
Votre FS n'a pas besoin d'être aussi compliqué: -F-ça va.
glenn jackman
Pour une saisie plus complexe, si vous ne savez pas si les champs précédents ont des espaces, vous pouvez utiliser une virgule comme séparateur de champ et exécuter le tout d' tr -d "- "abord.
Jason C
@glennjackman La façon dont j'interprète la question est que la valeur peut être non négative (pas de génération), ce qui rompt avec juste -F-.
Adrian Frühwirth
En effet, je n'avais pas lu cela de près.
glenn jackman
8

Vous pouvez utiliser cutpour sélectionner la 2e colonne de nombres et paste -sd+pour créer une série de nombres à additionner. L'outil bcpeut ensuite être utilisé pour effectuer le calcul.

$ cut -d',' -f2 pwpower.log | paste -sd+ | bc
-244.19

Comment ça fonctionne

Sélectionne les nombres dans la 2ème colonne.

$ cut -d',' -f2 pwpower.log 
 -114.10
 -130.09

Les reformate en une seule ligne avec un +signe entre chaque numéro:

$ cut -d',' -f2 pwpower.log | paste -sd+
 -114.10+ -130.09

Effectue le calcul:

$ cut -d',' -f2 pwpower.log | paste -sd+ | bc
-244.19

Pour obtenir la valeur absolue:

$ cut -d',' -f2 pwpower.log | sed 's/-//g' | paste -sd+ | bc
244.19

Si le format du fichier pwpower.logest garanti, vous pouvez avoir cutomis le signe moins:

$ cut -d'-' -f2 pwpower.log | paste -sd+ | bc
244.19
slm
la source
6

Une approche KISS

$ awk '{print -$2; t+=-$2}; END{print t}' pwpower.log 
114.1
130.09
244.19
tournevis
la source
1
BAISER? Qu'est-ce que c'est?
Bernhard
Garder les choses simples et stupides;)
Steeldriver
@sim oui mais sauf erreur de lecture, l'OP a spécifiquement demandé que le panneau soit retiré
steeldriver
@steeldriver - ah oui ma mauvaise, j'ai raté cette phrase enfouie dedans.
slm
4
Restez simple, stupide. Impliquer que lorsque vous ne restez pas simple, vous êtes stupide.
Matt
4

J'aime votre commande grep, mais elle pourrait être améliorée pour supprimer le signe moins et fonctionner dans les cas où il n'y a pas de signe moins. Les expressions régulières étendues disponibles dans GNU grep avec le -Edrapeau nous permettent de faire correspondre un nombre plus précisément.

Il est légèrement plus efficace de ne pas utiliser cat, mais passez le nom du fichier en argument à la première commande et laissez-le lire le fichier. Il me vient également à l'esprit que si vous ne traitez qu'avec la première ou la dernière ligne du fichier, il est plus logique d'utiliser d'abord les commandes headou tailafin de ne faire correspondre qu'une seule ligne avec grep.

Première valeur:

$ head -n 1 /tmp/pwpower.log | grep -oE '[0-9\.]+$' 
114.10

Dernière valeur:

$ tail -n 1 /tmp/pwpower.log | grep -oE '[0-9\.]+$'
130.09

Sum (avec la commande awk d' ici ):

$ grep -oE '[0-9\.]+$' /tmp/pwpower.log | awk '{s+=$1} END {print s}'
244.19
Stephen Ostermiller
la source
3
[root@ip-10-186-149-181 ~]# cut -d '-' -f2 /tmp/pwpower.log | paste -sd+ | bc
244.19

Cela fera le calcul sans le moins.

Je pense que la coupe est plus rapide que awk, en général

csny
la source
1

awkest l'outil, mais le nombre probablement peut être positif ( à droite?), ce qui signifie que vous ne pas à utiliser le signe moins comme séparateur de champ. À la place, utilisez la virgule comme séparateur de champ, puis annulez chaque valeur numériquement - awkconvertira automatiquement les chaînes en nombres pour vous:

$ awk -F, '{ print -$2 }' < /tmp/pwpower.log
114.1
130.09

S'il arrive qu'il y ait des nombres positifs, ils sortiront négatifs. Si vous ne voulez que la somme, vous awkpouvez aussi le faire:

$ awk -F, '{ sum += -$2 } END { print sum }' < /tmp/pwpower.log
244.19
zwol
la source
Dans awk, vous pouvez utiliser sqrt($2^2)une astuce pour obtenir une valeur absolue.
Jason C
@JasonC C'est intelligent, mais dans le contexte, je pense que ce serait la mauvaise chose à faire.
zwol
0

Pour additionner les deux valeurs:

(awk -F- '{printf "%s+", $2}' /tmp/pwpower.log; echo 0) | bc -l
le chaos
la source
Tout cela est un peu redondant. Pourquoi diable utiliser les options de calcul de awk?
Bernhard
1
oui, c'est vrai, mais j'aime bc=)
chaos
1
Oh, eh bien, alors pourquoi utiliser awk? echo $(cut -d- -f2 file | tr '\n' '+')0 | bc
Bernhard
@Bernhard Eh bien, pourquoi utiliser cut? Utilisez [insert_cmd_here]plutôt, générez une boucle de sous-shell, inventez de nouveaux mathématiques, utilisez un cluster humain ou une arithmétique mentale, canalisez mes pensées bc. Pourquoi faisons-nous des choses? Aucune raison de rendre ma réponse mauvaise.
chaos
0

Vous pouvez également utiliser sed

$-sed -r 's/[^-]+.(.*)/\1/g' /tmp/pwpower.log
Kalanidhi M.
la source