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?

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

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

6

Une approche KISS

$ awk '{print -$2; t+=-$2}; END{print t}' pwpower.log 
114.1
130.09
244.19

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

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


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

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

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.