Hi, I have 2 statements in a file
a.sh start time is Fri Jan 9 17:17:33 CST 2015
a.sh end time is Fri Jan 9 17:47:33 CST 2015
I am required to get only the time out of it. like
17:17:33 & 17:47:33
PLs suggest
Hi, I have 2 statements in a file
a.sh start time is Fri Jan 9 17:17:33 CST 2015
a.sh end time is Fri Jan 9 17:47:33 CST 2015
I am required to get only the time out of it. like
17:17:33 & 17:47:33
PLs suggest
What have you tried so far?
If the string is allways the same structure, then you can do something like this:
string1='a.sh start time is Fri Jan 9 17:17:33 CST 2015';
string1=${string1%* CST 2015}
string1=${string1##* }
string2='a.sh start time is Fri Jan 9 17:17:33 CST 2015';
string2=${string2%* CST 2015}
string2=${string2##* }
clear && echo $string1 && echo "" && echo $string2
try
awk 'match($0, /([0-9]+):([0-5]?[0-9]):([0-5]?[0-9])/, ary) {print ary[1]":"ary[2]":"ary[3]}' yourfile
@Don Cragun
ok sry
im new here
Hi,
I tried the below.
while read line
do
if echo "$line" | grep -q "started at"
then
st= ${line#*started at}
echo $st
fi
done < $load_time
but getting output as
temp.ksh[35]: Thu Jan 29 15:01:17 CST 2015: not found [No such file or directory]
I should get output as 15:01:17
You can't have a space between the variable= and the value to be assigned to that variable. The syntax you used, sets st to an empty string and includes it in the environment of the command that follows. But that won't get rid of the Thu Jan 29 or the CST 2015
Note that your original post didn't say anything about the string started at appearing in the input (and was not in your sample input).
Assuming you're working in an English locale, you could try something like:
awk '
match($0, /[[:digit:]]{1,2}:[[:digit:]]{2}:[[:digit:]]{2} *([AP]M){0,1}/) {
print substr($0, RSTART, RLENGTH)
}' file
The ERE can be simplified if you only have 24-hour format times.
With the following contents in your input file:
Nothing found on this line
a.sh start time is Fri Jan 9 17:17:33 CST 2015
a.sh end time is Fri Jan 9 17:47:33 CST 2015
Single digit hour Fri Jan 9 5:50:59 PM CST 2015
Double digit hour Sat Jan 10 11:22:33 AM CST 2015
No space single Fri Jan 9 5:50:59PM CST 2015
No space double Sat Jan 10 11:22:33AM CST 2015
it produces the output:
17:17:33
17:47:33
5:50:59 PM
11:22:33 AM
5:50:59PM
11:22:33AM
Fairly simple changes would allow you to find more than one timestamp on a line.
If you want to try this on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk
Hello Don,
Thank you for nice code, I think we need to add --re-interval in that as follows as we are using ERE here.
awk --re-interval '
match($0, /[[:digit:]]{1,2}:[[:digit:]]{2}:[[:digit:]]{2} *([AP]M){0,1}/) {
print substr($0, RSTART, RLENGTH)
}' Input_file
Output will be as follows.
17:17:33
17:47:33
Thanks,
R. Singh
Hi Ravinder,
--re-interval (or --posix ) is needed on gawk to get POSIX conforming EREs, but it is not needed for any version of awk that conforms to the POSIX standards.
The output that I showed in post #8 was the exact output produced by the awk command I showed in that thread when it was run on OS X Yosemite.
Could be quite easier 
Solution 1:
awk '{print $8}' afile.txt
Option 2:
while read vScript vStatus sTime sIs sDay sMonth sNum sTime sReg sYear
do echo "$sTime"
done<afile.txt
What you asked in first post, and what you described your post #7 does not match.
You're looking for the string "started at" but your example post #1, shows us there is only "start at".
If you care about the status, feel free to add a check for "vStatus", wether its "start" or "end".
hth
This will probably work for about half of a year's input assuming that all lines are in exactly the same format and that the CST is referring to US Central Standard timezone. It won't work when dayligth savings time is in effect. And, of course, it will only work for dates in 2015.
The following modifications should work year around for the sample input provided in 2015:
string1='a.sh start time is Fri Jan 9 17:17:33 CST 2015';
string1=${string1%* C?T 2015}
string1=${string1##* }
string2='a.sh start time is Fri Jun 12 17:17:33 CDT 2015';
string2=${string2%* C[DS]T 2015}
string2=${string2##* }
clear && echo $string1 && echo "" && echo $string2
The ? will match any character; the [DS] will match an uppercase D or an uppercase S . I will leave the modifications needed to recognize additional years as an exercise for the reader. If some of the dates being processed come from other timezones, I would suggest using a different approach.
You seem to be mixing the awk match() and split() functions. But, I get a syntax error when I try this code. The match() function takes two arguments (string to be matched and an ERE to match) and sets various awk variables to indicate whether or not a match was found and, if there was a match, the starting position of the match and the length of the match. The awk script I suggested in post #8 in this thread uses match() this way.
The awk split() function creates an array of values corresponding to values separated by field separators specify by an ERE. With the ERE you use, the desired date would not appear in the array at all since the ERE selects the date as the field separator.
Hi All, Thanks for replying. I tried Bigsanch's code modified by Don(#12). It worked fine for me. However need to do a thorough testing before implementing.
Also my original code wrked after removing the extra space after =(#8). But I am getting Thu Jan 29 15:01:17 CST 2015 in a variable. So I was looking if anyways I can extract only the time from the above.
The "from the above" is a little ambiguous. There are suggestions above in this thread from several volunteers trying to help you, most of which try to just extract a timestamp from your sample data.
What operating system and shell are you using? As has been pointed out, some of the suggestions above will work on some systems but not on others.
Instead of just giving us two strings to parse, describe the strings you want to parse:
[LEFT]Will the timezone always be CST? Always CST or CDT? Always US timezones?
What range of years do you need to cover?
Are you looking for a 24hr time only or can there be 12hr times (with AM or PM) as well?
Is the date in your string always preceded by the literal string a.sh start time is ? Why is there a space in front of that sometimes? If not, describe what will appear (number of words, anything containing a colon ( : ), etc.).[/LEFT]
Hi Don,
I`m getting the the following result when I run the code in cygwin
$ cat tmp
a.sh start time is Fri Jan 9 17:17:33 CST 2015
a.sh end time is Fri Jan 9 17:47:33 CST 2015
Single digit hour Fri Jan 9 5:50:59 PM CST 2015
Double digit hour Sat Jan 10 11:22:33 AM CST 2015
No space single Fri Jan 9 5:50:59PM CST 2015
No space double Sat Jan 10 11:22:33AM CST 2015
$ awk 'match($0, /([0-9]+):([0-5]?[0-9]):([0-5]?[0-9])/, ary) {print ary[1]":"ary[2]":"ary[3]}' tmp
17:17:33
17:47:33
5:50:59
11:22:33
5:50:59
11:22:33
Hi Don,
From "From the above" i meant Thu Jan 29 15:01:17 CST 2015.
i am using ksh.
timezones are always US timezones(CST or EST).Range of years should be 2010 to 2030.
Yes I am looking for 24 hrs time, no AM or PM.
Well i might have confused with the parse string, the file will contain strating like below:
a.ksh started at Thu Jan 29 15:01:17 CST 2015
a.ksh ended at Thu Jan 29 15:31:17 CST 2015
Thanks for the information. I wasn't aware of this non-standard extension to the match() function in cygwin's awk utility.
Isn't Cygwin's awk just GNU awk ?
It appears that it is. I wasn't aware that gawk had this non-standard extension to POSIX requirements either; but now that I'm looking for it, it is in the gawk(1) man page.
If you have a file that starts with two lines like those shown above and you just want to extract the start and end times, a ksh function just using ksh built-ins (as suggested by sea) seems to do what you want. If we save the Korn shell script:
#!/bin/ksh
# SYNOPSIS:
# gettimes [pathname]
# DESCRIPTION:
# Get the start and end timestamps from the first two lines in the file named
# by the pathname operand (default to standard input if no operand is
# specified) and write them to standard output separated by a space.
gettimes() {
# If called with an operand, redirect input from the file named by it...
if [ $# -gt 0 ]
then exec < "$1"
fi
# Get start time ($sTIME) from 1st line in input file...
read _prog _se _time _at _dow _mon _md sTime _TZ _yr
# Get end time ($eTIME) from 2nd line in input file...
read _prog _se _time _at _dow _mon _md eTime _TZ _yr
# Print the found start and end times...
printf '%s %s\n' "$sTime" "$eTime"
}
# Test function reading standard input passed into this script
times=$(gettimes)
printf 'gettimes function returned "%s"\n' "$times"
stime="${times% *}"
etime="${times#* }"
printf 'Read start time "%s" & end time "%s" from 1st 2 lines from stdin.\n' \
"$stime" "$etime"
# Test function reading data from a file named "file".
times=$(gettimes file)
printf '\n\ngettimes function returned "%s"\n' "$times"
stime="${times% *}"
etime="${times#* }"
printf 'Read start time "%s" & end time "%s" from 1st 2 lines from "file":\n' \
"$stime" "$etime"
head -n 2 file
in a file named tester and make it executable:
$ chmod +x tester
and invoke it with the command:
$ printf '%s\n' 'a.sh start time is Tue Feb 2 01:23:45 CST 2015' 'a.sh end time is Tue Feb 2 12:34:56 CST 2015' | ./tester
then we get the output:
gettimes function returned "01:23:45 12:34:56"
Read start time "01:23:45" & end time "12:34:56" from 1st 2 lines from stdin.
gettimes function returned "17:17:33 17:47:33"
Read start time "17:17:33" & end time "17:47:33" from 1st 2 lines from "file":
a.sh start time is Fri Jan 9 17:17:33 CST 2015
a.sh end time is Fri Jan 9 17:47:33 CST 2015
Which seems to be what you're trying to do.
Although written and tested using the Korn shell, this script will work with any shell that performs standard POSIX shell command substitution and variable expansions (such as ash , bash , dash , and ksh ).