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)}