解析ps'"etime"输出并将其转换为秒

Clo*_*eto 7 regex linux bash parsing type-conversion

这些是可能的输出格式 ps h -eo etime

21-18:26:30
   15:28:37
      48:14
      00:01
Run Code Online (Sandbox Code Playgroud)

如何解析它们几秒钟?

  • 请假设日期部分至少有3位数字,因为我不知道它可以有多长时间.
  • 输出将只egreped到一行,因此不需要循环.

use*_*001 14

用awk:

#!/usr/bin/awk -f  
BEGIN { FS = ":" }
{
  if (NF == 2) {
    print $1*60 + $2
  } else if (NF == 3) {
    split($1, a, "-");
    if (a[2] != "" ) {
      print ((a[1]*24+a[2])*60 + $2) * 60 + $3;
    } else {
      print ($1*60 + $2) * 60 + $3;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

运行:

awk -f script.awk datafile
Run Code Online (Sandbox Code Playgroud)

输出:

1880790
55717
2894
1
Run Code Online (Sandbox Code Playgroud)

最后,如果你想管道解析器,你可以这样做:

ps h -eo etime | ./script.awk
Run Code Online (Sandbox Code Playgroud)


Flu*_*ffy 14

另一种bash解决方案,适用于任意数量的领域:

ps -p $pid -oetime= | tr '-' ':' | awk -F: '{ total=0; m=1; } { for (i=0; i < NF; i++) {total += $(NF-i)*m; m *= i >= 2 ? 24 : 60 }} {print total}'

说明:

  1. 替换-:使得字符串变为1:2:3:4'1-2:3:4',将total设置为0并将乘数设置为1
  2. 拆分:,从最后一个字段(秒)开始,乘以m = 1,加到第二个总数,m变为60(一分钟内的秒数)
  3. 添加分钟字段乘以60,m变为3600
  4. 加上小时*3600
  5. 加天*3600*24

  • 在所有解决方案中,我认为在可维护性,可移植性和代码简单性方面,这是最优雅的解决方案. (2认同)

And*_*dor 12

这是我的Perl one liner:

ps -eo pid,comm,etime | perl -ane '@t=reverse split(/[:-]/,$F[2]); $s=$t[0]+$t[1]*60+$t[2]*3600+$t[3]*86400; print "$F[0]\t$F[1]\t$F[2]\t$s\n"'
Run Code Online (Sandbox Code Playgroud)

未定义的值呈现为零,因此它们不会对秒的总和产生影响.


小智 7

想想我可能会忽略这一点,但最简单的方法是:

ps h -eo etimes
Run Code Online (Sandbox Code Playgroud)

请注意etime结束时的"s".

  • centos 6 , ps不支持etimes (2认同)

小智 6

尝试使用sed + awk我的解决方案:

ps --pid $YOUR_PID -o etime= | sed 's/:\|-/ /g;' |\ 
awk '{print $4" "$3" "$2" "$1}' |\
awk '{print $1+$2*60+$3*3600+$4*86400}'
Run Code Online (Sandbox Code Playgroud)

它用sed分割字符串,然后向后反转数字("DD hh mm ss" - >"ss mm hh DD")并用awk计算它们.

$ echo 21-18:26:30 | sed 's/:\|-/ /g;' | awk '{print $4" "$3" "$2" "$1}' | awk '{print $1+$2*60+$3*3600+$4*86400}'
1880790
$ echo 15:28:37 | sed 's/:\|-/ /g;' | awk '{print $4" "$3" "$2" "$1}' | awk '{print $1+$2*60+$3*3600+$4*86400}'
55717
$ echo 48:14 | sed 's/:\|-/ /g;' | awk '{print $4" "$3" "$2" "$1}' | awk '{print $1+$2*60+$3*3600+$4*86400}'
2894
$ echo 00:01 | sed 's/:\|-/ /g;' | awk '{print $4" "$3" "$2" "$1}' | awk '{print $1+$2*60+$3*3600+$4*86400}'
1
Run Code Online (Sandbox Code Playgroud)

您也可以使用sed并从输入字符串中删除所有非数字字符:

sed 's/[^0-9]/ /g;' | awk '{print $4" "$3" "$2" "$1}' | awk '{print $1+$2*60+$3*3600+$4*86400}'
Run Code Online (Sandbox Code Playgroud)