BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

Hi Everyone,

 

I want to get the "last modified" timestamp of a file residing in a AIX filesytem.

 

When I use this AIX-command:

istat SASWebReportStudio4.4_KeyActions.log | grep modified |  awk '{print $3, $4, $5,  $6, $7, $8}'

I get this output:

Wed Jun 16 17:35:28 CEST 2021

Can someone tell me, how the heck I can get this into a decent SAS timestamp?

 

Thx

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

That's unfortunate. Your server admins should install the whole GNU coreutils package, it contains a lot of very useful tools (e.g. /usr/linux/bin/date has a lot of VERY USEFUL options for handling dates in shell scripts).

Use the built-in SAS functions:

data mod_time;
length fref $8;
rc = filename(fref,"/sas/conf/Lev1/Web/Logs/SASServer1_1/SASWebReportStudio4.4.log.2021-06-15");
fid = fopen(fref);
if fid ne 0
then do;
  timestamp = input(finfo(fid,foptname(fid,5)),nldatm.);
  rc = fclose(fid);
end;
rc = filename(fref);
format timestamp e8601dt19.;
run;

You need to use the NLS informat because the FINFO function returns the timestamp in your locale.

View solution in original post

10 REPLIES 10
Kurt_Bremser
Super User

/usr/linux/bin/ls provides a GNU ls with the option --time-style, which allows you to get ISO-compliant timestamps (which you can read with E8601/B8601 infornats).

FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

Good morning @Kurt_Bremser ,

 

unfortunately, I cannot find the GNU ls version under /usr/linux/bin/ls. Here is, what we have:

 

ls_not_there.JPG

 

Is there any other way?

Kurt_Bremser
Super User

That's unfortunate. Your server admins should install the whole GNU coreutils package, it contains a lot of very useful tools (e.g. /usr/linux/bin/date has a lot of VERY USEFUL options for handling dates in shell scripts).

Use the built-in SAS functions:

data mod_time;
length fref $8;
rc = filename(fref,"/sas/conf/Lev1/Web/Logs/SASServer1_1/SASWebReportStudio4.4.log.2021-06-15");
fid = fopen(fref);
if fid ne 0
then do;
  timestamp = input(finfo(fid,foptname(fid,5)),nldatm.);
  rc = fclose(fid);
end;
rc = filename(fref);
format timestamp e8601dt19.;
run;

You need to use the NLS informat because the FINFO function returns the timestamp in your locale.

FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

@Kurt_Bremser : one follow-up question:

 

Using your code, I get the filoption number 5 (Last Modified Date) without any seconds, which in turn creates a time stamp assuming that the seconds part is zero:

 

LastModified                   timestamp
18. Juni 2021 10.53 Uhr 1939632780
20. Mai 2021 02.31 Uhr 1937097060
22. Mai 2021 02.31 Uhr 1937269860
24. Mai 2021 02.31 Uhr 1937442660
26. Mai 2021 02.31 Uhr 1937615460
30. Mai 2021 02.31 Uhr 1937961060
01. Juni 2021 02.31 Uhr 1938133860
03. Juni 2021 02.31 Uhr 1938306660
05. Juni 2021 22.09 Uhr 1938550140
12. Juni 2021 02.31 Uhr 1939084260
16. Juni 2021 02.31 Uhr 1939429860

 

Is this due to the formats used? Woulde Do I have to change the widths of the respective formats?

How can I get the sconds part of the last modified date?

 

When looking at OS level, I can see that the seconds part should be "15", "45", "45", .... .

lm_os_level.JPG

 

Kurt_Bremser
Super User

Then we need to go back to the istat output.

Use the SCAN function to get the pieces.

The 3rd, 2nd and 5th concatenated can be INPUT with DATE9., and the 4th INPUT with TIME8. Then combine both with the DHMS function.

FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

Hi @Kurt_Bremser ,

 

the problem with using the istat-command way is, that you cannot give a wildcard-search for ALL KeyAction Logs ("Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log*"), because the command expects a specific, unique path to ONE file.

Therefore, I will have to iterate through all the KeyActions-Logfiles...

 

Nevertheless, the command and the transformation of the feedback of istat-command works:

 

%LET l_cmd = %nrbquote(istat /please/put/your/path/here/config/LevX/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log | grep modified |  awk '{print $3, $4, $5,  $6, $7, $8}');

/*set up pipe*/
filename oscmd pipe "&l_cmd.";

data work.test   ;
infile oscmd truncover;
input string $50. ;

format timestamp datetime25. date date9. time time8.;

date = input(scan(string,3)||scan(string,2)||scan(string,6),date9.);
time = input(scan(string,4), time8.);

timestamp = dhms(date, hour(time), minute(time), second(time));
run;
Kurt_Bremser
Super User

You can do this in one data step by use of the dynamic pipe:

data lognames;
infile datalines truncover;
input logfilepath $255.;
datalines;
/sas/conf/Lev1/Web/Logs/SASServer1_1/SASWebReportStudio4.4_KeyActions.log
;

data work.test;
set lognames;
length command $1000;
command = catx(" ","istat",logfilepath,"| grep modified |  awk '{print $3, $4, $5,  $6, $7, $8}'");
format timestamp datetime25. date date9. time time8.;
infile dummy pipe filevar=command end=done truncover;
do until (done);
  input string $50. ;
  date = input(scan(string,3)||scan(string,2)||scan(string,6),date9.);
  time = input(scan(string,4), time8.);
  timestamp = dhms(date, hour(time), minute(time), second(time));
  output;
end;
run;
FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

@Kurt_Bremser : Very elegant! However, this assumes, that I have to MANUALLY write every Logfilename into the datalines Statement:

 

data lognames ;
infile datalines truncover;
input logfilepath $255.;
datalines;
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210601_023145
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210603_023144
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210605_220912
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210612_023145
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210616_023148
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210619_023144
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210622_023142
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210624_023144
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210627_023144
/sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/SASWebReportStudio4.4_KeyActions.log_20210701_023144
;

Is there a way to AUTOMATICALLY let sas "fill in" the dataline lines? Maybe somehow with call execute?

So far, I can generate a dataset that list all the Logfiles:

%LET KeyActionPath = /sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/;
%LET KeyActionLogname = SASWebReportStudio4.4_KeyActions.log;
%LET ls_cmd = %nrbquote(ls -l &KeyActionPath.&KeyActionLogname.* |  awk '{ print $9 }');

/*set up pipe*/
filename oscmd pipe "&ls_cmd.";

data work.Liste_KeyactionLogs   ;
infile oscmd truncover;
input  logfilepath $255.  ;
run;

filename oscmd clear;

Voila:

Table_Logfilelist.JPG

 But how can I "plug in" this list into the datalines statement?

 

 

 

FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

@Kurt_Bremser : of course! Vor lauter Bäumen den Wald nicht gesehen!

Here is the complete (dense) code:

%LET KeyActionPath = /sas_install_web_p/config/Lev3/Web/Logs/SASServer2_1/;
%LET KeyActionLogname = SASWebReportStudio4.4_KeyActions.log;
%LET ls_cmd = %nrbquote(ls -l &KeyActionPath.&KeyActionLogname.* |  awk '{ print $9 }');

/*set up pipe*/
filename oscmd pipe "&ls_cmd.";

data work.KeyactionLogs_mit_ZS (keep=logfilepath timestamp);
infile oscmd truncover;
input  logfilepath $255.  ;
length command $1000;
command = catx(" ","istat",logfilepath,"| grep modified |  awk '{print $3, $4, $5,  $6, $7, $8}'");
format timestamp datetime25. date date9. time time8.;
infile dummy pipe filevar=command end=done truncover;
do until (done);
  input string $50. ;
  date = input(scan(string,3)||scan(string,2)||scan(string,6),date9.);
  time = input(scan(string,4), time8.);
  timestamp = dhms(date, hour(time), minute(time), second(time));
  output;
end;
run;

filename oscmd clear;

Thank you, Kurt!

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 10 replies
  • 1543 views
  • 2 likes
  • 2 in conversation