Grep resto della linea ... dopo la partita


8

Ho un file contenente solo due righe, con la seguente struttura:

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

I valori sono valori di potenza del mio impianto solare. Valore negativo significa generazione.

Avrei bisogno dei valori estratti tramite grep / sed / awk - qualunque sia il modo più intelligente. Devo avere entrambi i valori estratti separatamente e senza il segno meno.

Quello che faccio ora è un po 'stupido ma funziona - sono sicuro che molti di voi avranno modi più intelligenti per me :-) Qui ovviamente vedo solo i valori più il meno.

Per ottenere il primo valore:

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

Per ottenere il secondo valore:

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

E la domanda correlata, esiste un modo semplice per prendere queste STRING e trasformarle in modo da poter calcolare la somma?

Risposte:


12

Tutti i valori:

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

Valore sulla prima riga:

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

Valore sulla seconda riga:

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

Somma di tutti i valori:

$ awk -F '[ -]*' '{sum+=$NF} END{print sum}' /tmp/pwpower.log
244.19

1
Il tuo FS non deve essere così complicato: -F-lo farà.
Glenn Jackman,

Per input più complessi, se non sai se i campi precedenti hanno spazi, puoi usare una virgola come separatore di campo ed eseguire l'intero processo per tr -d "- "primo.
Jason C,

@glennjackman Il modo in cui interpreto la domanda è che il valore può essere non negativo (nessuna generazione) che si interrompe con giusto -F-.
Adrian Frühwirth,

Anzi, non l'avevo letto da vicino.
Glenn Jackman,

8

È possibile utilizzare cutper selezionare la seconda colonna di numeri e paste -sd+per creare una serie di numeri da sommare. Lo strumento bcpuò quindi essere utilizzato per eseguire il calcolo.

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

Come funziona

Seleziona i numeri dalla seconda colonna.

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

Riformattali in un'unica riga con un +accesso tra ogni numero:

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

Esegue il calcolo:

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

Per ottenere il valore assoluto:

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

Se il formato del file pwpower.logè garantito, puoi cutfare l'omissione del segno meno:

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

6

Un approccio KISS

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

1
BACIO? Cos'è quello?
Bernhard,

Keeping it Simple and Stupid;)
steeldriver,

@sim sì, ma a meno che non abbia letto male, l'OP ha chiesto espressamente di rimuovere il segno
steeldriver,

@steeldriver - ah sì, mio ​​male, ho perso quella frase sepolta lì dentro.
slm

4
Mantenerlo semplice, stupido. Implicare quando non lo fai semplice, sei stupido.
Matt,

4

Mi piace il tuo comando grep, ma potrebbe essere migliorato per rimuovere il segno meno e lavorare nei casi in cui non c'è segno meno. Le espressioni regolari estese disponibili in GNU grep con il -Eflag ci consentono di abbinare un numero in modo più preciso.

È leggermente più efficiente non usare cat, ma passare il nome del file come argomento al primo comando e lasciarlo leggere il file. Mi viene anche in mente che se hai a che fare solo con la prima o l'ultima riga del file, ha più senso usare prima i comandi heado in tailmodo da dover abbinare solo una riga con grep.

Primo valore:

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

Ultimo valore:

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

Somma (con il comando awk da qui ):

$ 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

Questo farà il calcolo senza il meno.

Penso che tagliare sia più veloce di Awk, in generale


1

awkè lo strumento giusto, ma probabilmente il numero può essere positivo (giusto?), il che significa che non si desidera utilizzare il segno meno come separatore di campo. Invece, usa la virgola come separatore di campo, quindi annulla ogni valore numericamente - awkconvertirà automaticamente le stringhe in numeri per te:

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

Se ci sono numeri positivi, ne usciranno negativi. Se vuoi solo la somma, awkpuoi farlo anche tu :

$ awk -F, '{ sum += -$2 } END { print sum }' < /tmp/pwpower.log
244.19

In awk puoi usare sqrt($2^2)come trucco per ottenere un valore assoluto.
Jason C,

@JasonC È intelligente, ma nel contesto credo che sarebbe la cosa sbagliata da fare.
zwol,

0

Per riassumere i due valori:

(awk -F- '{printf "%s+", $2}' /tmp/pwpower.log; echo 0) | bc -l

Tutto questo è un po 'ridondante. Perché mai il nog usa le opzioni di calcolo di awk?
Bernhard,

1
sì, vero, ma mi piace bc=)
caos,

1
Oh, bene, allora perché usarlo awk? echo $(cut -d- -f2 file | tr '\n' '+')0 | bc
Bernhard,

@ Bernard: Perché usarlo cut? Usa [insert_cmd_here]invece, genera un ciclo subshell, inventa nuovi calcoli matematici, usa un ammasso umano o un'aritmetica mentale, convoglia i miei pensieri bc. Perché facciamo le cose? Nessun motivo per rendere la mia risposta negativa.
caos,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.