开发者

awk-1-liner to sum numbers in stdin, while printing number of occurrences of certain text along with other arbritrary text

I'm definitely interested in getting a book on awk. I've been won over, despite playing with it for little time. However, in the mean time, I have a problem I suspect I could solve exclusively with [g]awk. To demonstrate, I'll use some fdisk output. In this example, the desired end result would be something like:

Disks: 2 [240 GB total]
sda=120 GB
sdb=120 GB

Here's what I have:

fdisk -l 2>/dev/null | awk '/^Disk \/dev\/[vsh]d./ {bytes+=$5} END {print "Disks: "NR" ["; gb=bytes/1024/1024/1024; print gb" GB total]"}'

My NR apparently prints out 73.. on my laptop with two hard drives, anyway. This, I do not understand. So far, well.. I'm maybe half-w开发者_如何学JAVAay there. Any tips or succinct tutorials would be greatly appreciated!


After two major excellent answers, I ended up with the following:

echo DISKS: $(fdisk -l 2>/dev/null | awk -F/ '/^Disk \/dev\/[vsh]d.|^Disk \/dev\/xvd./{print$3}' | awk '{d++;bytes+=$4;disk[$1]=$2" "$3}END{gb=bytes/1024/1024/1024; printf gb" GB total, "d" disks\n";for (i in disk) print "  "i,disk[i]}' | sed -e "s/,$/ /" -e "s/: / /")

Which gave me output like this:

DISKS: 78.3585 GB total, 2 disks
  sda 80.0 GB
  sdb 4110 MB

Looking forward to the day I can do that all in one awk command with no sed. :) But for now, thanks folks!


$ fdisk -l 2>/dev/null | awk '/^Disk \/dev\/[vsh]d./{d++;bytes+=$5;disk[$2]=$3$4} END {printf "Disks: "d" ["; gb=bytes/1024/1024/1024; printf gb" GB total]\n";for (i in disk) print i,disk[i]}'
Disks: 1 [93.1604 GB total]
/dev/sda: 100.0GB,


You're more than half way. The only issue is that NR is the number of rows (so far), not the number of rows matching your expression. So just use another variable for that.

fdisk -l 2>/dev/null | awk '/^Disk \/dev\/[vsh]d./ {bytes+=$5; disks+=1} END {print "Disks: "disks" ["; gb=bytes/1024/1024/1024; print gb" GB total]"}'

That gives:

Disks: x [
yyy GB total]

To remove the newline, and add output for each drive, try:

fdisk -l 2>/dev/null | awk '/^Disk \/dev\/[vsh]d./ {cur_bytes=$5; bytes+=cur_bytes; disks+=1; gsub(/dev|:|\//, "", $2); print $2 "=" cur_bytes/1024/1024/1024 " GB";} END {printf "Disks: "disks" ["; gb=bytes/1024/1024/1024; print gb" GB total]"}'

That gives:

sda=xx GB
sdb=yy GB
sdc=zz GB
Disks: 3 [ww GB total]

It doesn't print the header first. You could use concatenation to do that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜