stampf.awk

The stampf.awk library provide 2 functions you can use in your awk programs:

  • stampf(format)
    This function return a string construct from format.
    Format usage (look in source code for exemples):

    • %n NanoSec

    • %s SinceEpochSec

    • %(p|P) ProcID|Program name

    • %(r|R) (single shot|Repeating) random

    • %% %

    • %c processor number

    • %(g|G) group

    • %(u|U) user

    • %Tc tree pid path and c=character use as separator

  • proc_info(rinfo, ARRAY, command)
    This function is use whit stampf() and can have any uses.

Arguments:

    • rinfo: return info item from ARRAY, using one of in the next list
      (command,comm,psr,user,uid,group,gid,sess,ppid,pid,output,ps_info,ps)

    • ARRAY: contain process info items from command

    • command: from which process info are collected

For shell usage:

logs=`awk -v filelog="%P_%T-_%s_%n.log" -f stampf.awk`


For testing:

awk -v test_proc_info=1 -v test_stampf=1 -v filelog="%P_%T-_%s_%n.log" -f stampf.awk

awk -v test_stampf=1 -v filelog="%P_%T-_%s_%n.log" -f stampf.awk

awk -v test_proc_info=1 -v filelog="%P_%T-_%s_%n.log" -f stampf.awk


# -*- version-control: t; -*-

# Time-stamp: <CJ2K: [stampf.awk] 2016-08-12 12:21:51 edt>


# stampf.awk is licensed under the terms of the LGPLv2.1

# http://opensource.org/licenses/LGPL-2.1


# Copyright (c) 2011,2012,2013,2014,2015,2016,

# Jacques Champagne (cj2k*).

#

# All rights reserved.

#

# This library is free software; you can redistribute it and/or

# modify it under the terms of the GNU Lesser General Public

# License as published by the Free Software Foundation; either

# version 2.1 of the License, or (at your option) any later version.

#

# This library is distributed in the hope that it will be useful,

# but WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

# Lesser General Public License for more details.

#

# You should have received a copy of the GNU Lesser General Public

# License along with this library; if not, write to the Free Software

# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,

# MA 02110-1301 USA

#


############################################################[^%]? %%p %%%p

# Stamp format for temp filename and array indexes

# Return hex number and/or string stamp from format.

# format: %n NanoSec, %s SinceEpochSec,

# %p|P ProcID|Program name,

# %(r|R) (single shot|Repeating) random,

# %% %, %c processor number,

# %(g|G) group, %(u|U) user,

# %Tc tree pid path and c=character separator


# require:

# procps-ng version 3.3.3

# date (GNU coreutils) 8.13

# available in Debian distrOS


# for shell usage:

# logs=`awk -v filelog="%P_%T-_%s_%n.log" -f stampf.awk`


# for testing:

# awk -v test_proc_info=1 -v test_stampf=1 -v filelog="%P_%T-_%s_%n.log" -f stampf.awk

# awk -v test_stampf=1 -v filelog="%P_%T-_%s_%n.log" -f stampf.awk

# awk -v test_proc_info=1 -v filelog="%P_%T-_%s_%n.log" -f stampf.awk

BEGIN{

session = proc_info("sid", _PI_, ARGV[0])


if(filelog) print logs=stampf(filelog)

else logs=stampf("%P_%T-_%s_%n.log")


if(test_proc_info){

print "\n\tTest proc_info()\n">>logs

for(i in _PI_)

print i ":\t>" _PI_[i] "<" >>logs

fflush(logs); close(logs)

}


if(test_stampf){

print "\n\tTest stampf()\tsession: "session"\n",

"\ndefault stamp: "stampf(),

"\nsec.nano: "stampf("%s.%n"),

"\nprocess: "stampf("%P:%p"),

"\ngroup: "stampf("%G:%g"),

"\nuser: "stampf("%U:%u"),

"\nprocessor number:"stampf("uP:%c"),

"\npidpath: "stampf("%%, -\n\t%T%%\n\t%T-"),

"\nrandom: "stampf("%r-%r-%R-%R-%R-%R"),

"\n\nTest results of _STAMP\n">>logs

for(i=0; i<=_STAMP[0]; i++)

print i ":\t>" _STAMP[i] "<"\

(("F"i in _STAMP)? "\n\t"_STAMP["F"i]:"") >>logs

fflush(logs); close(logs)

}

}


############################################################

# Stamp format for temp filename and array indexes

# awk -v test_stampf=1 -v filelog="%P_%T-_%s_%n.log" -f stampf.awk

function stampf(f, c,S,N,SN,e,s,t,tpid,f0,f1,Z){

f1 = f = (!f?"%s_%n":f); gsub(/%%/, "\001",f); f0=f;

if(f0~/%[ns]/){

srand();# e=agvs(rand(),"+");

c="date '+%s.%N_'"; c|getline SN; close(c);

S= substr(SN,1,index(SN,".")-1);

N= substr(SN,index(SN,".")+1,index(SN,"_")-1);

gsub(/%n/,sprintf("%08X", N),f);

gsub(/%s/,sprintf("%08X", S),f);

#agvs(e);

}

if(f0~/%[rR]/){

gsub(/%r/,sprintf("%06X", rand()*10000000),f);

while(f~/%R/) sub(/%R/,sprintf("%06X", rand()*10000000),f)

}

if(length(_PI_) && f0~/%[cpPuUgGT]/){

if(f~/%c/) gsub(/%c/, sprintf("%X", _PI_["psr"]),f);

if(f~/%p/) gsub(/%p/, sprintf("%04X", _PI_["pid"]),f);

if(f~/%P/) gsub(/%P/, _PI_["comm"],f);

if(f~/%u/) gsub(/%u/, sprintf("%04X", _PI_["uid"]),f);

if(f~/%U/) gsub(/%U/, _PI_["user"],f);

if(f~/%g/) gsub(/%g/, sprintf("%04X", _PI_["gid"]),f);

if(f~/%G/) gsub(/%G/, _PI_["group"],f);

while(f~/%T./){

tpid=_PI_["tpid"]; s=substr(f,index(f,"%T")+2,1);

gsub(/:/, s, tpid); sub(/%T./, tpid, f)}

}

gsub(/\001/,"%",f); _STAMP["F"++_STAMP[0]]=f1

return _STAMP[_STAMP[0]]=f}


############################################################

# Get information of current process.

# awk -v test_proc_info=1 -v filelog="%P_%T-_%s_%n.log" -f stampf.awk

function proc_info(ret,P,a, c,p,E){# i,e, #srand(); e=agvs(rand(),"+");

E["$0"]=$0; E["NF"]=NF; E["RS"]=RS; E["FS"]=FS; RS="\n"; FS=" ";


P["command"]=a;

P["ps_info"]="comm,psr,user,uid,group,gid,sess,ppid,pid";

P["ps"]="ps -C '"P["command"]"' h -o \""P["ps_info"]"\"";

P["ps"]|getline p; close(P["ps"]); P["output"] = $0 = p;

if( P["command"] == $1 ){

P["comm"] =$1; # command

P["psr"] =$2; # processor number

P["user"] =$3; # user name

P["uid"] =$4; # user id

P["group"]=$5; # group name

P["gid"] =$6; # group id

P["sid"] =$7; # session id

P["ppid"] =$8; # parent process id

P["pid"] =$9; # process id

P["tpid"] = sprintf("%X", ( p = $9 ) );

while(p > 0){ # tree path of process ids

c="ps -p "p" h -o ppid"; c|getline p; close(c);

P["tpid"] = sprintf("%X", p)":"P["tpid"]}

} else P["ERROR"] = "ERROR: something wrong with ps command\n'"\

P["command"]"': \t"P["output"]; # agvs(e);

RS=E["RS"]; FS=E["FS"]; $0=E["$0"]; NF=E["NF"];# Delete(E);

return length(ret) && ret in P && length(P[ret])? P[ret]: P["tpid"]}


############################################################

# experimentals

function strL(s,c){return substr(s,1,index(s,c)-1)}

function strR(s,c){return substr(s,index(s,c)+length(c))}

function Delete(A){return !split("",A)}