sed + 查找行中单词之前的值

sed + 查找行中单词之前的值

如何找到“免费”一词之前的值?

top -n1 | grep Mem                   
Mem:  2054968k av, 2034120k used,   20848k free,       0k shrd,  186768k buff

首先我尝试过

  top -n1 | grep Mem  | awk '{print $7}'

但这并不好,因为免费值(此处为 20848k)可以位于不同的字段中。有时是字段 6,有时是字段 7,依此类推。

我需要它在 Linux 和 Solaris 上都能工作。

答案1

$ top -bn1 | grep free
KiB Mem:   8117084 total,  6578888 used,  1538196 free,   302216 buffers
KiB Swap:  8060924 total,    26004 used,  8034920 free,  1564856 cached
$ top -bn1 | grep -oP '\S+(?=\s+free)'
1544132
8034920

需要 GNU grep,但你已经标记了“linux”,所以没问题

仅针对“Mem”:

top -bn1 | grep -oP 'Mem.*\s\K\S+(?=\s+free)'

答案2

awk -v RS="[, ]" '/free/{print a}{a=$0}'

解释

  • 将记录分隔符设置为,space,因此每个字符串前面的数字本身就是一条记录,该字符串也是一条记录。
  • 将所有内容作为自己的记录,awk 将逐项处理每一项
  • 对于之前的所有记录,free它会忽略,{print a}因为条件不匹配,并且会跳到{a=$0}将当前处理的记录存储在变量中a
  • 一旦/free/匹配,awk 将仅查找包含匹配之前的记录的{print a}位置a

答案3

使用 GNU sed(仅限 Linux):

top -bn1 | sed -rn '/Mem/{s/.* ([^ ]*) free.*/\1/p;}'

使用任何sed

top -bn1 | sed -n '/Mem/{s/.* \([^ ]*\) free.*/\1/p;}'

使用perl

top -bn1 | perl -lne '/Mem.* ([\d]+)\s*free/ && print $1'

使用专为该工作设计的工具(在 Linux 上测试,不确定是否free在 Solaris 上可用):

free | awk '/Mem/{print $4}'

另一个专为这项工作设计的工具(应该在 Linux 和 Solaris 上运行):

vmstat 2 2 | tail -n 1 | awk '{print $4}'

转到源代码(这适用于 Linux,不确定是否适用于 Solaris):

awk '/MemFree/{print $2}' /proc/meminfo 

相关内容