split date and time collide with space between them in bash - bash

from my wp cli I receive a date format like this :
YYYY-mm-ddHH-mm-ss for example : 2020-02-2514:24:25
I would like to convert it to timestamp but the format date is incorrect.
I would like to split the date and time with space between them but I have no idea to do that currently.
with regex may be but I just seen how to replace space and I am a nooby with bash regex.
thank you for your help

Just use cut
root#a036fb1c94fa:~# DATE=$(echo "2020-02-2514:24:25" | cut -b-10)
root#a036fb1c94fa:~# TIME=$(echo "2020-02-2514:24:25" | cut -b11-)
root#a036fb1c94fa:~# TIMESTAMP=$(date -d "$DATE $TIME" +"%s")
root#a036fb1c94fa:~# echo $TIME
14:24:25
root#a036fb1c94fa:~# echo $DATE
2020-02-25
root#a036fb1c94fa:~# echo $TIMESTAMP
1582637065
Explanation:
echo "2020-02-2514:24:25" | cut -b-10
echo the string and cut it before the 10th byte
echo "2020-02-2514:24:25" | cut -b11-
echo the string and cut it from the 11th byte until the end
echo date -d "$DATE $TIME" +"%s"
give the right format to unix date command, with +"%s" to get its timestamp

You don't need any regex. You can select substrings in bash.
If the variable wpdate contains the string returned by wp cli, the corresponding timestamp can be put into the variable timestamp as follows:
timestamp=$(date '+%s' --date "${wpdate:0:10} ${wpdate:10:8}")
Explanation: ${wpdate:10:8} means the substring of wpdate starting at position 10 and containing 8 chars.

Related

Shell Date conversion and assign to Variable

I have requirement like convert a string date to below format and assign to variable for futher processing.
Input is string as below
str = 20210709
Need to get yesterday date and change the format to %Y-%m-%d
(date -d 'str -1 days' +'%Y-%m-%d')
and i am expecting output in a variable like below
dt = 2021-06-09
I tried like below
dt = date -d '20210709 -1 days' +'%Y-%m-%d'
and the error as below
-bash: d: command not found
Any ideas/Suggestions would be greatly appreciated.
You're missing a couple of things:
3.5.4 Command Substitution syntax
no spaces allowed around the = for variable assignment
str=20210709
dt=$(date -d "$str - 1 day" '+%F')
echo "$dt"
2021-07-08
dt=$(paste -d "-" <(echo $str |cut -c1-4) <(echo $str |cut -c5-6) <(echo $str |cut -c7-8))
If your version of linux doesn't like that syntax, then
dt=$(sed 's/\(....\)\(..\)\(..\)/\1-\2-\3/' <<< $str)

How to write a shell script to perform below changes in the Parameter file

I am looking to write a shell script that finds and replaces the parameter values every time a workflow is run. I am a beginner and trying to learn more about this.
For example
-$$mp_Custom_Filter_D_Prem=AND BLSB.BLSB_CREATE_DTM <= '2019-02-28'
--$$mp_Custom_Filter_D_LEP=AND convert(date,(substring(SBSR.SBSR_SOURCE,9,2)+substring(SBSR.SBSR_SOURCE,5,2)+substring(SBSR.SBSR_SOURCE,7,2))) <= '2019-02-28'
I have these 2 parameters in the file and I want the script to change the dates to advance a month and set its last day.
So far the date 2019-02-28 I would like the script to find the dates and replace it to 2019-03-31.
I have tried the below script and its not the same result
PRM_FIL_DIR=$1 PRM_FIL_NME=$2 LOG_FIL_DIR=$3 LOG_FIL_NME=$4 echo Begining of the log File > $LOG_FIL_DIR/$LOG_FIL_NME From=`grep '$$mp_Custom_Filter_D_Prem=AND BLSB.BLSB_CREATE_DTM <' $PRM_FIL_DIR/$PRM_FIL_NME | awk -F= '{print $3}'|uniq| sed "s/'//g" | awk '$1=$1' ` echo $From is Date value found in $PRM_FIL_DIR/$PRM_FIL_NME parameter File >> $LOG_FIL_DIR/$LOG_FIL_NME To=`date -d "$From 2 month -1 day" +%Y-%m-%d` echo $To is the value to be replaced in $PRM_FIL_DIR/$PRM_FIL_NME parameter File >> $LOG_FIL_DIR/$LOG_FIL_NME From_FNL="'$From'" To_FNL="'$To'" sed -i "s/$From_FNL/$To_FNL/g" "$PRM_FIL_DIR/$PRM_FIL_NME" echo Date values replaced >> $LOG_FIL_DIR/$LOG_FIL_NME echo End of the log File >> $LOG_FIL_DIR/$LOG_FIL_NME PRM_FIL_DIR=$1 PRM_FIL_NME=$2 LOG_FIL_DIR=$3 LOG_FIL_NME=$4 echo Begining of the log File > $LOG_FIL_DIR/$LOG_FIL_NME From=`grep '$$mp_Custom_Filter_D_Prem=AND BLSB.BLSB_CREATE_DTM <' $PRM_FIL_DIR/$PRM_FIL_NME | awk -F= '{print $3}'|uniq| sed "s/'//g" | awk '$1=$1' ` echo $From is Date value found in $PRM_FIL_DIR/$PRM_FIL_NME parameter File >> $LOG_FIL_DIR/$LOG_FIL_NME To=`date -d "$From 2 month -1 day" +%Y-%m-%d` echo $To is the value to be replaced in $PRM_FIL_DIR/$PRM_FIL_NME parameter File >> $LOG_FIL_DIR/$LOG_FIL_NME From_FNL="'$From'" To_FNL="'$To'" sed -i "s/$From_FNL/$To_FNL/g" "$PRM_FIL_DIR/$PRM_FIL_NME" echo Date values replaced >> $LOG_FIL_DIR/$LOG_FIL_NME echo End of the log File >> $LOG_FIL_DIR/$LOG_FIL_NME
I want the output to be the last day of the month i.e 2019-03-31 and actual output is 2019-03-29
Try this flow,
lastmonth=$( date -d "-$(date +%d) days" +%Y%m%d)
currentmonth=$( date -d "-$(date +%d) days month" +%Y%m%d)
sed "s/$lastmonth/$currentmonth/g" filename.txt

What is causing my md5 hash to come out incorrectly?

#!/bin/bash
# Program's Purpose: Compute time elapsed between epoch time and current time
# Produce an MD5 hash from that time
# Get code from that hash
# compute time elapsed in seconds between epoch time and current time
#EPOCH=$(date -u -d '2001-02-03 04:05:06' '+%F %H:%M:%S')
#CURRENT=$(date -u -d '2010-06-13 12:55:34' '+%F %H:%M:%S')
# code: dd15
EPOCH=$(date -u -d '1999-12-31 23:59:59' '+%F %H:%M:%S')
CURRENT=$(date -u -d '2013-05-06 07:43:25' '+%F %H:%M:%S')
# interval is time elapsed minus time elapsed % 60
echo $EPOCH
echo $CURRENT
read YEAR1 M1 DAY1 HOUR1 MIN1 SEC1 <<< "${EPOCH//[:-]/ }"
read YEAR2 M2 DAY2 HOUR2 MIN2 SEC2 <<< "${CURRENT//[:-]/ }"
echo $YEAR1 $M1 $DAY1 $HOUR1 $MIN1 $SEC1
# date in seconds from
sec1=$(date -d "$EPOCH" -u +%s)
sec2=$(date -d "$CURRENT" -u +%s)
echo $sec1
echo $sec2
# get the difference from the two times
difference=$((sec2 - sec1))
difference=$((difference - ((difference % 60))))
echo $difference
# get the hash from the time
hash=$(echo -n $difference | md5sum | tr -d '\n')
hash=$(echo -n $hash | md5sum | tr -d '\n')
echo $hash
# creating two strings, one with all of the letters
# the other with all of the numbers
letter=$(echo $hash | sed 's/[0-9]*//g' | cut -c1-2)
echo $letter
num=$(echo $hash | sed 's/[^0-9]*//g')
echo $num
#num=$(echo $num | cut -c1-2)
#echo $num
# getting the last two numbers in reverse order
num1=$(echo ${num: -1})
num=$(echo "${num::-1}")
echo $num
num2=$(echo ${num: -1})
code="$letter$num1$num2"
echo $code
I'm trying to write a program that takes an epoch time and
current time, computes the difference in seconds, and then creates a
code by doing a double md5 hash on the time in seconds. By what times
I have entered in currently, the difference in seconds should be 421,
141, 406, and the 'code' is supposed to be based on 60-second
intervals, so the code I'm trying to generate should come from 421,
141, 380.
The resulting hash should be
042876ca07cb2d993601fb40a1525736, but I am getting
d49904f9e7e62d0ff16e523d89be08eb. Can anyone tell me what I'm doing
wrong exactly?
I read that bash leaves a newline at the end of
strings, so I ran echo with -n option to remove that newline, but I am
still not getting the preferred results.
The output of md5sum on many platforms is not just the MD5 sum. For example, on a GNU/Linux system, you get
debian$ echo -n 401 | md5sum
816b112c6105b3ebd537828a39af4818 -
Notice that the output has two fields: The actual MD5 sum, followed by two spaces, followed by the input file name (where - stands for standard input).
(By contrast, on OSX, and I would expect most *BSDs, you get
yosemite$ echo -n 401 | md5
816b112c6105b3ebd537828a39af4818
Here, you'll notice that the name of the MD5 utility is different.)
The fix should be simple. I have refactored your code to (a) prefer the portable printf over the less portable echo -n; (b) remove the completely superfluous final tr -d '\n' (newlines are trimmed off the end of the captured variable by the shell already); and (c) fold everything into a single pipeline.
hash=$(printf '%s' "$difference" | md5sum | cut -d ' ' -f 1 | tr -d '\n' |
md5sum | cut -d ' ' -f 1)
echo "$hash"
For completeness, this code also has proper quoting; it's not strictly necessary here (but it would have been if you really needed to preserve the spacing in the value you originally obtained from md5sum, for example) but omitting quotes is a common newbie problem which should be avoided.
(Capturing a variable just so you can echo it is also a common newbie antipattern; but your code will want to use the variable hash subsequently.)
Repeated code is always a bad smell; maybe provide a function which performs the same job as the *BSD md5 utility;
md5 () { md5sum "$#" | cut -d ' ' -f 1; }
hash=$(printf '%s' "$difference" | md5 | tr -d '\n' | md5)

shell $ character overwrites the previous variable

I'm trying to write a script on shell but I'm stucked on a point.
I have a program creating data daily and puting it to a directory like this: home/meee/data/2013/07/22/mydata
My problem is I'm trying to change directory using date. Here is my script:
#!/bin/sh
x=$(date -u -v-2H "+%Y-%m-%d")
echo $x
year=$(echo $x | cut -d"-" -f1)
month=$(echo $x | cut -d"-" -f2)
day=$(echo $x | cut -d"-" -f3)
echo $year
echo $month
echo $day
d1='/home/sensor/data/'${year}/${month}
echo $d1
There is no problem related to year, day, month, they are working. But the output of echo d1 is /07me/sensor/data/2013. Similarly, when I write echo $year$day it gives 2312 (characters of day is overwritten on the first two characater of the year)
I tried many other syntax like instead of ' character put " or leave it empty. Removing { and so on. But nothing changed.
Shortly, when I write two variable ($var1 $var2) in same line the second $ behaves like go to the beginning of the line and start overwriting the first variable.
I've been looking for that but there is nothing related to that or I couldn't find anything related and there are a lot of solution in Stackoverflow that solves the problem using $var1$var2
What am I doing wrong, or how can I solve that.
I'm working on FreeBSD 9.0-RELEASE amd64 and using sh
Any help will be appreciated.
Thanks
Somehow, your commands are introducing carriage returns to your variables, which affect the output when the variable is not the last thing echoed. You can confirm this by passing the value through hexdump or od:
printf "%s" "$x" | hexdump -C # Look for 0d in the output.
printf "%s" "$year" | hexdump -C # Look for 0d in the output.
printf "%s" "$month" | hexdump -C # Look for 0d in the output.
printf "%s" "$day" | hexdump -C # Look for 0d in the output.
I don't think this will fix the problem, but you can get the year, month, and day without forking so many external programs:
IFS=- read year month day <<EOF
$(date -u -v-2H "+%Y-%m-%d")
EOF
or more simply
read year month day <<EOF
$(date -u -v-2H "+%Y %m %d")
EOF
You’re likely using MinGW or some other not-quite-Unix environment for Windows®, which is introducing Carriage Return (CR, \r) characters at end-of-line (from the Unix PoV).
So change this to either:
x=$(date -u -v-2H "+%Y-%m-%d" | sed $'s/\r$//')
echo $x
year=$(echo $x | cut -d"-" -f1 | sed $'s/\r$//')
month=$(echo $x | cut -d"-" -f2 | sed $'s/\r$//')
day=$(echo $x | cut -d"-" -f3 | sed $'s/\r$//')
Or, even better:
x=$(date -u -v-2H "+%Y %m %d ")
echo $x
set -- $x
year=$1
month=$2
day=$3
Note the extra space after %d which ensures that the CR will become $4 instead of attached to the day.

YYYY-MM-DD format date in shell script

I tried using $(date) in my bash shell script, however, I want the date in YYYY-MM-DD format.
How do I get this?
In bash (>=4.2) it is preferable to use printf's built-in date formatter (part of bash) rather than the external date (usually GNU date).
As such:
# put current date as yyyy-mm-dd in $date
# -1 -> explicit current date, bash >=4.3 defaults to current time if not provided
# -2 -> start time for shell
printf -v date '%(%Y-%m-%d)T\n' -1
# put current date as yyyy-mm-dd HH:MM:SS in $date
printf -v date '%(%Y-%m-%d %H:%M:%S)T\n' -1
# to print directly remove -v flag, as such:
printf '%(%Y-%m-%d)T\n' -1
# -> current date printed to terminal
In bash (<4.2):
# put current date as yyyy-mm-dd in $date
date=$(date '+%Y-%m-%d')
# put current date as yyyy-mm-dd HH:MM:SS in $date
date=$(date '+%Y-%m-%d %H:%M:%S')
# print current date directly
echo $(date '+%Y-%m-%d')
Other available date formats can be viewed from the date man pages (for external non-bash specific command):
man date
Try: $(date +%F)
The %F option is an alias for %Y-%m-%d
You can do something like this:
$ date +'%Y-%m-%d'
$(date +%F)
output
2018-06-20
Or if you also want time:
$(date +%F_%H-%M-%S)
can be used to remove colons (:) in between
output
2018-06-20_09-55-58
You're looking for ISO 8601 standard date format, so if you have GNU date (or any date command more modern than 1988) just do: $(date -I)
date -d '1 hour ago' '+%Y-%m-%d'
The output would be 2015-06-14.
With recent Bash (version ≥ 4.2), you can use the builtin printf with the format modifier %(strftime_format)T:
$ printf '%(%Y-%m-%d)T\n' -1 # Get YYYY-MM-DD (-1 stands for "current time")
2017-11-10
$ printf '%(%F)T\n' -1 # Synonym of the above
2017-11-10
$ printf -v date '%(%F)T' -1 # Capture as var $date
printf is much faster than date since it's a Bash builtin while date is an external command.
As well, printf -v date ... is faster than date=$(printf ...) since it doesn't require forking a subshell.
I use the following formulation:
TODAY=`date -I`
echo $TODAY
Checkout the man page for date, there is a number of other useful options:
man date
if you want the year in a two number format such as 17 rather than 2017, do the following:
DATE=`date +%d-%m-%y`
I use $(date +"%Y-%m-%d") or $(date +"%Y-%m-%d %T") with time and hours.
I used below method. Thanks for all methods/answers
ubuntu#apj:/tmp$ datevar=$(date +'%Y-%m-%d : %H-%M')
ubuntu#apj:/tmp$ echo $datevar
2022-03-31 : 10-48
Whenever I have a task like this I end up falling back to
$ man strftime
to remind myself of all the possibilities for time formatting options.
Try to use this command :
date | cut -d " " -f2-4 | tr " " "-"
The output would be like: 21-Feb-2021
#!/bin/bash -e
x='2018-01-18 10:00:00'
a=$(date -d "$x")
b=$(date -d "$a 10 min" "+%Y-%m-%d %H:%M:%S")
c=$(date -d "$b 10 min" "+%Y-%m-%d %H:%M:%S")
#date -d "$a 30 min" "+%Y-%m-%d %H:%M:%S"
echo Entered Date is $x
echo Second Date is $b
echo Third Date is $c
Here x is sample date used & then example displays both formatting of data as well as getting dates 10 mins more then current date.
You can set date as environment variable and later u can use it
setenv DATE `date "+%Y-%m-%d"`
echo "----------- ${DATE} -------------"
or
DATE =`date "+%Y-%m-%d"`
echo "----------- ${DATE} -------------"
echo "`date "+%F"`"
Will print YYYY-MM-DD
Try this code for a simple human readable timestamp:
dt=$(date)
echo $dt
Output:
Tue May 3 08:48:47 IST 2022

Resources