如何从bash中的日志中找到PID的第一个实例

时间:2017-09-15 06:47:44

标签: bash awk grep

我有一组如下日志:

sept 4 00:00:00 ntp[123]: some message like send start
sept 4 00:00:00 ntp[123]: some message like starting
sept 4 00:00:01 ntp[123]: some message like started
sept 4 00:00:01 dhcp[234]: some message like i am server
sept 4 00:00:02 dhcp[234]: some message like i am client
sept 4 00:00:05 ntp[345]: some message this line is special
sept 4 00:00:08 bash[555]: some message like any message
sept 4 00:00:08 bash[555]: some message like any message
sept 4 00:00:09 bash[555]: some message like any message
sept 4 00:00:10 GLITCH bash[556]: some message like any message
sept 4 00:00:10 bash[555]: some message like any message

禁止输出:

sept 4 00:00:00 ntp[123] started or respawned
sept 4 00:00:01 dhcp[234] started or respawned
sept 4 00:00:05 ntp[345] started or respawned
sept 4 00:00:10 bash[556]: started or respawned
sept 4 00:00:10 bash[555] started or respawned

从上面的日志集中,我需要找到生成或重生的进程。我必须使用脱机日志集来执行此操作。

以下我只能打印进程及其PID,但我还需要时间戳

grep -Po '\w+\[\d+\]' local.log |awk '!a[$0]++ {print $0 , "respawned or started "}'
ntp[123] respawned or started
dhcp[234] respawned or started
ntp[345] respawned or started
bash[556] started or respawned
bash[555] respawned or started

任何提示?

注意:这不会有帮助,因为process[PID]位置每行不同。

awk '!a[$4]++ {print $1,$2,$3 , "respawned or started "}'

2 个答案:

答案 0 :(得分:2)

使用awk:

$ awk -F'[][]' '!a[$2]++ {print $1 "[" $2 "] started or respawned"}' local.log
sept 4 00:00:00 ntp[123] started or respawned
sept 4 00:00:01 dhcp[234] started or respawned
sept 4 00:00:05 ntp[345] started or respawned
sept 4 00:00:08 bash[555] started or respawned
sept 4 00:00:10 GLITCH bash[556] started or respawned

如何运作

  • -F'[][]'

    这告诉awk使用[]作为字段分隔符。在这种情况下,进程ID将是字段2 $2

    更深入:在正则表达式中,[...]匹配方括号内的任何字符。在我们的示例中,我们希望组中的字符为[],因此我们编写[][]。我们可以这样做,因为规则是]如果它是组中的第一个字符,则不会结束组。

  • !a[$2]++ {print $1 "[" $2 "] started or respawned"}

    a[$2]是我们到目前为止看到进程ID $2的次数。 !a[$2]++第一次是真的,之后是假的。

    更深入: a[$2]在我们第一次遇到PID时为零,之后为正。在awk中,零为假,非零为真。我们想要与此相反:我们想要在[$ 2]为零时进行打印。因此,我们用!否定逻辑条件。然后,!a[$2]仅在a[$2]为零时才为真。尾随++递增a[$2]但仅在评估逻辑值之后。

    !a[$2]++为真时,awk将在大括号中执行打印所需输出的命令。

替代

使用printf格式化输出以代替print

$ awk -F'[][]' '!a[$2]++{printf "%s[%s] started or respawned\n",$1,$2}' local.log
sept 4 00:00:00 ntp[123] started or respawned
sept 4 00:00:01 dhcp[234] started or respawned
sept 4 00:00:05 ntp[345] started or respawned
sept 4 00:00:08 bash[555] started or respawned
sept 4 00:00:10 GLITCH bash[556] started or respawned

答案 1 :(得分:0)

awk 解决方案(适用于大多数awk实施):

this.opcionesAutocompleteClientes.opcionStyle = this.opcionStyle;

输出:

SELECT  SEC_TO_TIME( SUM( TIME_TO_SEC( `timeSpent` ) ) ) AS timeSum  
FROM YourTableName

或GNU awk 解决方案:

awk 'match($0, /\<[[:alnum:]]+\[[0-9]+\]:/){ pid=substr($0,RSTART,RLENGTH); 
     if(!a[pid]++) print $1,$2,$3,pid" respawned or started" }' logfile

输出:

sept 4 00:00:00 ntp[123]: respawned or started
sept 4 00:00:01 dhcp[234]: respawned or started
sept 4 00:00:05 ntp[345]: respawned or started
sept 4 00:00:08 bash[555]: respawned or started
sept 4 00:00:10 bash[556]: respawned or started
相关问题