Phần còn lại của đường thẳng sau trận đấu


8

Tôi có một tệp chỉ chứa hai dòng, với cấu trúc sau:

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

Các giá trị là giá trị năng lượng của nhà máy năng lượng mặt trời của tôi. Giá trị âm có nghĩa là thế hệ.

Tôi sẽ cần các giá trị được trích xuất thông qua grep / sed / awk - bất cứ cách nào là cách thông minh nhất. Tôi cần phải có cả hai giá trị được trích xuất riêng biệt và không có dấu trừ.

Những gì tôi làm bây giờ là loại ngu ngốc nhưng nó hoạt động - Tôi chắc chắn nhiều bạn sẽ có những cách thông minh hơn cho tôi :-) Tất nhiên ở đây tôi chỉ thấy các giá trị cộng với Minus.

Để có được giá trị đầu tiên:

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

Để có được giá trị thứ hai:

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

Và câu hỏi liên quan, có cách nào đơn giản để lấy các chuỗi này và biến đổi để tôi có thể tính toán SUM không?

Câu trả lời:


12

Tất cả các giá trị:

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

Giá trị trên dòng đầu tiên:

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

Giá trị trên dòng thứ hai:

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

Tổng của tất cả các giá trị:

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

1
FS của bạn không cần phải phức tạp đến thế: -F-sẽ làm được.
glenn jackman

Đối với đầu vào phức tạp hơn, nếu bạn không biết các trường trước có khoảng trắng hay không, bạn có thể sử dụng dấu phẩy làm dấu tách trường và chạy toàn bộ thông qua tr -d "- "trước.
Jason C

@glennjackman Cách tôi diễn giải câu hỏi là giá trị có thể không âm (không tạo ra) mà chỉ dừng lại ở đó -F-.
Adrian Frühwirth

Thật vậy, tôi đã không đọc kỹ điều đó.
glenn jackman

8

Bạn có thể sử dụng cutđể chọn cột số thứ 2 và paste -sd+tạo một chuỗi số để cộng lại với nhau. Công cụ bcnày sau đó có thể được sử dụng để thực hiện tính toán.

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

Làm thế nào nó hoạt động

Chọn các số từ cột thứ 2.

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

Định dạng lại chúng thành một dòng duy nhất với một +dấu hiệu ở giữa mỗi số:

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

Thực hiện tính toán:

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

Để có được giá trị tuyệt đối:

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

Nếu định dạng của tệp pwpower.logđược đảm bảo, bạn có thể cutbỏ qua dấu trừ:

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

6

Một cách tiếp cận KISS

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

1
HÔN? Đó là gì?
Bernhard

Giữ cho nó đơn giản và ngu ngốc;)
Steeldo

@sim có nhưng trừ khi tôi đọc sai, OP đặc biệt yêu cầu xóa dấu hiệu
Steeldo

@steel ấn - à vâng, tôi xấu, tôi đã bỏ lỡ câu đó.
slm

4
Giữ cho nó đơn giản ngu ngốc. Để ám chỉ khi bạn không giữ nó đơn giản, bạn thật ngu ngốc.
Matt

4

Tôi thích lệnh grep của bạn, nhưng nó có thể được cải thiện để loại bỏ dấu trừ và hoạt động trong trường hợp không có dấu trừ. Các biểu thức chính quy mở rộng có sẵn trong GNU grep với -Ecờ cho phép chúng tôi khớp một số chính xác hơn.

Nó không hiệu quả hơn một chút khi không sử dụng cat, nhưng chuyển tên tệp làm đối số cho lệnh đầu tiên và để nó đọc tệp. Tôi cũng nhận thấy rằng nếu bạn đang xử lý chỉ các dòng đầu tiên hoặc cuối cùng từ tệp, thì việc sử dụng các lệnh headhoặc tailtrước sẽ hợp lý hơn để bạn chỉ phải khớp một dòng với grep.

Giá trị đầu tiên:

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

Giá trị cuối cùng:

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

Sum (với lệnh awk từ đây ):

$ 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

Điều này sẽ làm phép tính mà không có điểm trừ.

Tôi nghĩ rằng cắt giảm nhanh hơn awk, nói chung


1

awklà công cụ phù hợp, nhưng số có thể có thể dương (phải không?), có nghĩa là bạn không muốn sử dụng dấu trừ làm dấu tách trường. Thay vào đó, hãy sử dụng dấu phẩy làm dấu tách trường, sau đó phủ định từng giá trị bằng số - awksẽ tự động chuyển đổi chuỗi thành số cho bạn:

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

Nếu có bất kỳ số dương nào, chúng sẽ phát ra âm. Nếu bạn chỉ muốn tổng, awkcũng có thể làm điều đó:

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

Trong awk bạn có thể sử dụng sqrt($2^2)như một mẹo để có được giá trị tuyệt đối.
Jason C

@JasonC Điều đó thật thông minh, nhưng trong bối cảnh tôi tin rằng đó là điều sai trái.
zwol

0

Để tổng hai giá trị:

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

Tất cả điều này là một chút dư thừa. Tại sao trên trái đất nog sử dụng các tùy chọn tính toán của awk?
Bernhard

1
vâng, đúng, nhưng tôi thích bc=)
hỗn loạn

1
Ohw, tốt, sau đó tại sao sử dụng awk? echo $(cut -d- -f2 file | tr '\n' '+')0 | bc
Bernhard

@Bernhard À, sao lại dùng cut? [insert_cmd_here]Thay vào đó, sử dụng một vòng lặp phụ, phát minh ra toán học mới, sử dụng một cụm người hoặc số học tinh thần, đưa suy nghĩ của tôi vào bc. Tại sao chúng ta làm việc? Không có lý do để làm cho câu trả lời của tôi xấu.
hỗn loạn

0

Bạn cũng có thể sử dụng sed

$-sed -r 's/[^-]+.(.*)/\1/g' /tmp/pwpower.log
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.