Grep sisa baris ... setelah pertandingan


8

Saya memiliki file yang hanya berisi dua baris, dengan struktur berikut:

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

Nilai-nilai tersebut adalah nilai daya pembangkit listrik tenaga surya saya. Nilai negatif berarti generasi.

Saya membutuhkan nilai yang diekstrak melalui grep / sed / awk - apa pun cara yang paling cerdas. Saya perlu kedua nilai diekstraksi secara terpisah dan tanpa tanda minus.

Apa yang saya lakukan sekarang agak bodoh tetapi berhasil - saya yakin banyak dari Anda akan memiliki cara yang lebih cerdas untuk saya :-) Di sini tentu saja saya hanya melihat nilai plus Minus.

Untuk mendapatkan nilai pertama:

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

Untuk mendapatkan nilai kedua:

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

Dan pertanyaan terkait, apakah ada cara sederhana untuk mengambil STRING dan mentransformasikannya sehingga saya dapat menghitung SUM?

Jawaban:


12

Semua nilai:

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

Nilai pada baris pertama:

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

Nilai pada baris kedua:

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

Jumlah semua nilai:

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

1
FS Anda tidak perlu sesulit itu: -F-akan dilakukan.
glenn jackman

Untuk input yang lebih kompleks, jika Anda tidak tahu apakah bidang sebelumnya memiliki spasi, Anda dapat menggunakan koma sebagai pemisah bidang dan menjalankan semuanya melalui tr -d "- "terlebih dahulu.
Jason C

@glennjackman Cara saya menginterpretasikan pertanyaan adalah bahwa nilainya bisa non-negatif (tidak ada generasi) yang rusak hanya dengan -F-.
Adrian Frühwirth

Memang, saya belum membaca dengan cermat.
glenn jackman

8

Anda dapat menggunakan cutuntuk memilih kolom angka 2, dan paste -sd+untuk membuat serangkaian angka untuk ditambahkan bersama. Alat bctersebut kemudian dapat digunakan untuk melakukan perhitungan.

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

Bagaimana itu bekerja

Pilih angka dari kolom ke-2.

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

Format ulang menjadi satu baris dengan +masuk di antara setiap nomor:

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

Melakukan perhitungan:

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

Untuk mendapatkan nilai absolut:

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

Jika format file pwpower.logdijamin Anda bisa cutmelakukan menghilangkan tanda minus:

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

6

Pendekatan KISS

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

1
CIUMAN? Apa itu?
Bernhard

Keeping it Simple and Stupid;)
steeldriver

@sim ya tapi kecuali saya salah membaca, OP secara khusus meminta tanda untuk dihapus
steeldriver

@steeldriver - ah ya salahku, aku merindukan kalimat yang terkubur di sana.
slm

4
Tetap sederhana, bodoh. Untuk menyiratkan ketika Anda tidak membuatnya sederhana, Anda menjadi bodoh.
Matt

4

Saya suka perintah grep Anda, tetapi bisa ditingkatkan untuk menghapus tanda minus, dan bekerja dalam kasus ketika tidak ada tanda minus. Ekspresi reguler yang diperluas tersedia dalam GNU grep dengan -Ebendera memungkinkan kami untuk mencocokkan nomor dengan lebih tepat.

Ini sedikit lebih efisien untuk tidak menggunakan cat, tetapi meneruskan nama file sebagai argumen ke perintah pertama dan biarkan membaca file. Itu juga terjadi pada saya bahwa jika Anda hanya berurusan dengan baris pertama atau terakhir dari file, lebih masuk akal untuk menggunakan headatau tailperintah terlebih dahulu sehingga Anda hanya perlu mencocokkan satu baris dengan grep.

Nilai pertama:

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

Nilai terakhir:

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

Jumlah (dengan perintah awk dari sini ):

$ 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

Ini akan melakukan perhitungan tanpa minus.

Saya pikir memotong lebih cepat daripada awk, secara umum


1

awkadalah alat yang tepat, tetapi jumlahnya mungkin bisa positif (kanan?), yang berarti Anda tidak ingin menggunakan tanda minus sebagai pemisah bidang. Alih-alih, gunakan koma sebagai pemisah bidang, lalu negasikan setiap nilai secara numerik - awkakan secara otomatis mengonversi string menjadi angka untuk Anda:

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

Jika kebetulan ada angka positif, mereka akan keluar negatif. Jika Anda hanya menginginkan jumlahnya, awkdapat melakukannya juga:

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

Dalam awk Anda dapat menggunakan sqrt($2^2)sebagai trik untuk mendapatkan nilai absolut.
Jason C

@JasonC Itu pintar, tetapi dalam konteks saya percaya itu akan menjadi hal yang salah untuk dilakukan.
zwol

0

Untuk menjumlahkan dua nilai:

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

Ini semua agak berlebihan. Mengapa nog bumi menggunakan opsi perhitungan awk?
Bernhard

1
ya, benar, tapi saya suka bc=)
kekacauan

1
Ohw, well, lalu mengapa menggunakan awk? echo $(cut -d- -f2 file | tr '\n' '+')0 | bc
Bernhard

@ Bernhard Yah, mengapa menggunakan cut? Gunakan [insert_cmd_here]sebagai gantinya, buat loop subkulit, ciptakan matematika baru, gunakan kluster manusia atau aritmatika mental, sambungkan pikiran saya ke dalam bc. Mengapa kita melakukan banyak hal? Tidak ada alasan untuk membuat jawaban saya salah.
kekacauan

0

Anda dapat menggunakan sed juga

$-sed -r 's/[^-]+.(.*)/\1/g' /tmp/pwpower.log
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.