Tôi chạy lệnh sau:
grep -o "[0-9] errors" verification_report_3.txt | awk '{print $1}'
và tôi nhận được kết quả sau:
1
4
0
8
Tôi muốn thêm từng số vào một biến đếm đang chạy. Có một phép thuật ai đó có thể giúp tôi xây dựng?
Tôi chạy lệnh sau:
grep -o "[0-9] errors" verification_report_3.txt | awk '{print $1}'
và tôi nhận được kết quả sau:
1
4
0
8
Tôi muốn thêm từng số vào một biến đếm đang chạy. Có một phép thuật ai đó có thể giúp tôi xây dựng?
Câu trả lời:
grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }'
Điều đó không in danh sách nhưng không in tổng. Nếu bạn muốn cả danh sách và tổng, bạn có thể làm:
grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1; print $1} END { print SUM }'
variable=$(grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }')
Điều này đặt đầu ra của lệnh (chỉ là giá trị tổng) vào biến có tênvariable
"[0-9]\+ errors"
. Điều này sẽ khớp nếu bạn có một báo cáo dòng> 9 lỗi.
Điều này cũng có thể được thực hiện trong awk:
awk '"[0-9]+ errors" {sum += $1}; END {print sum}' verification_report_3.txt
Dường như bạn đang sử dụng hệ thống GNU , vì vậy nếu hỗ trợ biểu thức chính quy Perl có sẵn, bạn có thể viết một cái gì đó như thế này:
grep -Po '[0-9]+(?=\s+errors)' infile |
paste -sd+ |
bc
PS I đã sửa đổi biểu thức chính quy (đã thêm + bộ định lượng) để cho phép các số> 9.
PS Ngoài ra, awk là đủ (giả sử GNU awk ):
awk 'END { print s }
/[0-9]+[[:space:]]+errors/ {
s += $1
}' infile
Hãy thử đường ống đầu ra từ grep của bạn vào
awk 'BEGIN {total=0;}{total+=$1;}END {print "Total: ",total}'
Tôi sử dụng cái này:
$ echo $(cat file | sed 's/$/+/') 0 | bc
Nó không hiệu quả cho các danh sách lớn, nhưng đối với hầu hết các trường hợp sử dụng của tôi thì không sao. Tôi thường sử dụng hàm shell để tự động hóa quy trình để tôi chỉ phải cung cấp tên tệp:
## cheezy summation
## call from .bashrc
##
getsum () { echo $(cat $1 | sed 's/$/+/') 0 | bc; }
gethsum () { echo $(cat $1 | sed 's/[gG]/*1000M/' | sed 's/[mM]/*1000K/' | sed 's/[kK]/*1000/' | sed 's/$/+/') 0 | bc; }
gethexsum () { echo ibase=16 $(cat $1 | sed 's/$/+/') 0 | bc; }
Bạn luôn có thể thay thế điểm đánh dấu cuối dòng cho một dấu tách phần tử hoặc lớp ký tự cụ thể nếu dữ liệu của bạn được phân cách theo kiểu khác.