使用带有 w 命令的 sed 管道显示空闲时间最长的用户

Using sed piped with w command show user with the largest idle time

w 命令产生如下内容:

01:19:02 up 53 days, 10:44, 15 users,  load average: 0.00, 0.02, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
higrheht pts/5    c-13-76-207-161. 23:21    2:05   0.07s  0.07s -bash
sgergrgr pts/6    c-97-164-31-14.h 00:54    2.00s  0.04s  0.04s -bash
jwegrgrng pts/14   c-23-71-12-251.h 22:48    8:03   0.07s  0.06s vim s2
hiqrefan pts/18   c-13-31-206-169. 23:19    0.00s  0.01s  0.01s -bash
hqeffran pts/19   c-19-71-206-169. 23:19    1:58m  0.02s  0.02s -bash
aqrgri   pts/20   c-84-6-212-27.hs 23:21    0.00s  0.19s  0.17s -bash

我必须得到一个打印空闲时间最长的用户的 sed 脚本。但问题是 w 以 3 种不同的格式显示空闲时间:1) 以秒为单位:以 's' 结尾,2) mm:ss(不以 'm' 或 [=18= 结尾) ]),以及 3) hh:mm(以 'm' 结尾)。所以我需要以某种方式制作一个可以使用它的 sed 脚本,但我似乎做不到。

我的尝试: 有 2 个变量,首先设置它们只是为了找出最高空闲时间是在形式 1 还是 2 或 3 中。该部分已完成。然后基于此,我将提取该空闲字段中的文本并将其与变量进行比较,如果时间更长则替换。但是它最后有一个字母!所以它不能作为一个数字进行比较。它是一个字符串。就是这个问题。

BEGIN{view1=0
view3=0
userid=""
idlemax=""}

NR>2{
        if( ~ /s$/)
        {
            view2=1
        }

        if( ~ /m$/)
        {
          view3= 1
        }

}

除了使用 sed,您还可以使用 bash:

    #!/bin/bash

    decode_seconds()
    {
        echo "${1%%.*}"
    }

    decode_hrs()
    {
      echo $(( $( decode_pair "") * 60 ))
    }

    decode_pair()
    {
      local value=""
      local right="${value##*:}"
      local left="${value%%:*}"
      echo $(( (left * 60 ) + right ))
    }

    decode_value()
    {
      local value=""
      local units=""

      case "${units}" in 
        seconds) decode_seconds "${value}" ;;
        hours)   decode_hrs "${value}" ;;
        *)       decode_pair "${value}" ;;
      esac
    }

    process_data()
    {
      while read user value units extra ; do 
        echo $(decode_value "${value}" "${units}") "${user}"
      done
    }

    w | awk '{print ,}' \
      | sed \
        -e 's/s$/ seconds/' \
        -e 's/m$/ hours/' \
      | process_data \
      | sort -rn

空闲时间不比用户登录的TTY设备的最后访问时间复杂。因此,一个简单的方法是获取人们登录的所有 TTY 的名称,并且 stat 他们:

who -s | awk '{ print  }' | (cd /dev && xargs stat -c '%n %U %X')

在某些系统上,这会为不在真实 ttys 上的登录会话(例如 X11 会话)发出错误。

如果您想要年龄而不是绝对时间,post-process 将其从当前时间中减去:

who -s | awk '{ print  }' | (cd /dev && xargs stat -c '%n %U %X') |
    awk '{ print "\t""\t"'"$(date +%s)"'- }'

或使用perl-A运算符:

who -s | perl -lane 'print "$F[1]\t$F[0]\t" . 86400 * -A "/dev/$F[1]"'

来自here