I have the following CHECK that works fine in Linux (and Unix) to grep for a specific error "java.lang.OutOfMemoryError" the logs of up to -5 min from current date and time:
CHECK=$(awk -v d1="$(date --date="-5 min" "+[%-m/%-d/%y %H:%M:%S:%3N EEST]")" '$0 > d1' trace.log | grep "java.lang.OutOfMemoryError")
The logs have always the following timestamp format at each line (example):
[4/18/16 12:23:57:998 EEST]
I am trying to do the same at Solaris, but I get the following error response:
date: illegal option -- date=-5 min
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
I have been looking for a solution but I cannot find a convenient one yet. I have found some info for date and time manipulation with perl and python, but they are not easy to use and transform to do the same as I need above (especially perl appears to quite tricky, I am not familiar). So, maybe perl and python are not the answer here.
Can you please help me to do the job ?
Thank you.
Related
Here is what my log file look like
[BCDID::16 T::LIVE_ANALYZER GCDID::16] {"t":"20:50:05","k":"7322","h":"178","s":-53.134575556764}
[BCDID::16 T::LIVE_ANALYZER GCDID::16] {"t":"20:50:06","k":"2115","h":"178","s":-53.134575556764}
[BCDID::16 T::LIVE_ANALYZER GCDID::16] {"t":"20:50:07","k":"1511","h":"178","s":-53.134575556764}
There are multiple log files with similar entries and they are updated every second.
here "t" : "20:50:05" is Time.
What I want to do is, get all logs between specific time from all files from the end of the files.
I tried with tail files*.log | grep -e "20:50:07 | 20:50:05" but it does not return anything.
How do I get get all log entries between given time, starting from the end of file from all logs files?
If you're looking for a range for records, and the format of the lines is consistent, the easiest way is probably to isolate the time field, strip out the colons, and leverage the power of arithmetic operators.
A one-liner awk solution, for example:
tail files*.log | awk -v from="205006" -v to="205007" -F"\"" '{ timeasint=$4; gsub(":","",timeasint); if (timeasint >= from && timeasint <= to) print $0 }'
would get you:
[BCDID::16 T::LIVE_ANALYZER GCDID::16] {"t":"20:50:06","k":"2115","h":"178","s":-53.134575556764}
[BCDID::16 T::LIVE_ANALYZER GCDID::16] {"t":"20:50:07","k":"1511","h":"178","s":-53.134575556764}
Of course you couldn't span across midnight (i.e., 25:59:59 - 00:00:01), but for that you'd need dates as well as times in your log anyway.
If you had dates, my suggestion would be converting them to epoch stamps (using date -d "string" or some other suitable method) and comparing the epoch stamps as integers.
As pre requirement, I need to fetch last month date in Unix (solaris) csh.
set Lmit_Date=`date --date='1 month ago' +%Y%m%d`
above command will fetch last month date and working fine in Linux server. But our server is Solaris and mentioned command is not working.
Please can anyone suggest how I can fetch the last month date
The issue is due to the fact you are using a GNU date extension. --date is non standard.
Moreover, due to the fact month lengths are variable, the date displayed by GNU date might be unexpected, to say the least...
For example today is March 31 but "last month" date was March the 2nd according to GNU date:
$ date +%Y%m%d
20160331
$ date --date='1 month ago' +%Y%m%d
20160302
If you still want to either use GNU date on Solaris or find some workarounds, have a look to these replies:
https://stackoverflow.com/a/23507108/211665 and https://stackoverflow.com/a/17817087/211665
You should be able to compile coreutils for your solaris platform, which will provide you with the right date utility. But as coreutils overwrites core utilities as the name says, you may want to install this into a custom path and select the right date command through your special path, say "/opt/coreutils/bin/date".
The other method would be to calculate last month with a symbolic date output split
eval `date +"set YEAR=%Y; set MONTH=%m ;set DAY=%d"`
Now you can operate on "$YEAR", "$MONTH" and "$DAY". For example
let 'MONTH--'
if [ "$MONTH" -eq 0 ]; then MONTH=12; let 'YEAR--'; fi
set Lmit_Date=`date --date "$MONTH$DAY0000$YEAR" +"%Y%m%d"`
kind of. (I'm used to bash so I don't know if let is available here. But there are some other methods to shell calculations. There might be another keyword for csh).
Also you need to take care for number of days per month with the $DAY parameter.
function last_day {
y=`echo $1 | cut -f1 -d "-"`
m=`echo $1 | cut -f2 -d "-"`
d=`cal ${m} ${y} | nawk 'NF{A=$NF}END{print A}'`
echo "$y $m $d" | nawk '{printf("%s-%02d-%02d",$1,$2,$3);}'
} # last_day
last_day 2023-01-01
Will give you: 2023-01-31 in non-GNU Solaris.
I have a shell script that will check a file is how many days old. I did stat -f "%m%t%Sm %N" "$file" . But I want to store this into a variable and then compare current time and file created time ?
Assuming you're using bash, you can capture the output of commands with something like:
fdate=$(stat -f "%m%t%Sm %N" "$file")
and then do whatever you will with the results:
echo ${fdate}
That's assuming the command itself works in the first place. If you are, you can ignore the text below.
The GNU stat program uses -f to specify you want to query the filesystem rather than a file and the other options you have don't seem to make sense in the context of your question.
Using Gnu stat, you can get the time since the last file update(1) as:
ageInSeconds=$(($(date -u +%s) - $(stat --printf "%Y" "file")))
The subtracts the last modification time of the file from the current time (both expressed as seconds since the epoch) to give you the age in seconds.
To turn that into days, assuming you're not overly concerned about the possible error from leap seconds (an error of, at most, one part in about 15.7 million, or 0.000006%), you can just divide it by 86,400:
ageInDays=$((($(date -u +%s) - $(stat --printf "%Y" "file")) / 86400))
(1) Note that, although stat purports to have a %W format specifier that gives the birth of the file, this doesn't always work (it returns zero). You could check that first if you're really interested in when the file was created rather than last updated but you may have to be prepared to accept the possibility the information is not available. I've used last modification time above since, frequently, it's used for things like detecting changes.
I've been bashing my head into the wall for some time on this one.
I have a date string in my (ksh) script. It's not the current time, it's some arbitrary time.
How can I convert that date string into a Unix timestamp? I'm working on SunOS 5.10 and AIX, which don't have the date -d option, nor the MacOS date -j -f options.
I only need to do this conversion in one place in my code, so ideally I'd like to do it in one line, but if I have to create a function then so be it
I've messed around with Python and Perl to achieve this in one line. Python came the closest, but I couldn't get it to account for time zone, which I would really like. Any help would be much appreciated.
I lost whatever I had been trying to do with Python earlier, but looking back at it I've found a solution:
python -c 'import datetime, time;print time.mktime(datetime.datetime.strptime("08/22/2014/16", "%m/%d/%Y/%H").timetuple())'
This particular command outputs 1408737600, which is 4pm on August 22 2014 on the east coast.
I'm writing an autoconf script that needs the current UTC offset. There's no obvious way to get this out of the date program. Is there any straightforward way to get this from a command-line utility, or should I write a test that gets the information and somehow captures it?
Try this, and see whether it works for you:
date +%z
For others doing ISO8601, you might pick some variant of:
date +%Y%m%dT%H%M%S%z # 20140809T092143-0700
date -u +%Y%m%dT%H%M%S%z # 20140809T162143+0000
date -u +%Y%m%dT%H%M%SZ # 20140809T162143Z
I like those because the lack of punctuation supports universal use. Note that the capital Z is 'hard-coded' for UTC - using %Z will put UTC or the other named timezone. If you prefer punctuation:
date +%Y-%m-%dT%H:%M:%S%z # 2014-08-09T09:21:43-0700
date +%Y-%m-%dT%H:%M:%S%:z # 2014-08-09T09:21:43-07:00 - NOT ALL SYSTEMS
date -u +%Y-%m-%dT%H:%M:%S%z # 2014-08-09T16:21:43+0000
date -u +%Y-%m-%dT%H:%M:%S%:z # 2014-08-09T16:21:43+00:00 - NOT ALL SYSTEMS
date -u +%Y-%m-%dT%H:%M:%SZ # 2014-08-09T16:21:43Z
Consult man strftime as supported formats vary. For instance, some systems support inserting colons into the offset using %:z, %::z, or %:::z - only two of my five systems do (Debian, Ubuntu do, but Mac, BusyBox, QNX do not).
And I often go back to https://en.wikipedia.org/wiki/ISO_8601 for reference.
Yes, date can do this:
[tomalak#lolphin:~] date -R
Mon, 02 May 2011 17:37:45 +0100
Or, more specifically:
[tomalak#lolphin:~] date -R | awk '{print $6}'
+0100
[tomalak#lolphin:~] date +%z
+0100
Reading date --help is very useful.