Shell Date conversion and assign to Variable - bash

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)

Related

split date and time collide with space between them in 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.

How to evaluate date from a string

Here are my files :
conf.txt
case1:fooYYYYmmdd.bar
case2:helloYYYYmmdd.world
script.sh
fname=`grep $1 conf.txt | cut -d ':' -f2`
When calling my script.sh with a parameter being case1 or case2, I obviously get my var fname fed with fooYYYYmmdd.bar or helloYYYmmdd.world.
How could I evaluate the date from my conf.txt so fname would be set with foo20181120.bar and hello20181120.world without going through breaking and building back my string ?
You could just declare a Date variable and use it in fname, like this:
Date=$(date +%Y%m%d)
fname=$(grep $1 conf.txt |sed "s/YYYYmmdd/$Date/g"|cut -d ':' -f2)
echo $fname

Assing a variable and use it inside of if statement shell scripting

I am new to shell scripting and trying to make a few small scripts. I got stuck when i tried to write if condition. In the code below i am trying to get the $5 value from df and trying to use it in if condition. However the code doesn't work.
#!/bin/sh
temp = $(df -h | awk '$NF=="/"{$5}')
if [ $temp > 60 ] ; then
df -h | awk '$NF=="/" {printf("%s\n"),$5}'
(date -d "today" +"Date:%Y.%m.%d"" Hour: %H:%M")
fi
#end
So i've figured out something and changed my code into this:
temp=$(df -h | awk '$NF=="/"{$5}')
if [ "$((temp))" -gt 0 ] ; then
df -h | awk '$NF=="/" {printf("%s\n"),$5}'
(date -d "today" +"Date:%Y.%m.%d"" Hour: %H:%M")
fi
#end
And now , i'm trying to get the integer value of the $5 variable. It returns a percentage and i want to compare this percentage with %60. How can i do that ?
Let's see what shellcheck.net has to tell us:
Line 1:
#!/bin/sh
^-- SC1114: Remove leading spaces before the shebang.
Line 3:
temp = $(df -h | awk '$NF=="/"{$5}')
^-- SC1068: Don't put spaces around the = in assignments.
Line 4:
if [ $temp > 0 ] ; then
^-- SC2086: Double quote to prevent globbing and word splitting.
^-- SC2071: > is for string comparisons. Use -gt instead.
^-- SC2039: In POSIX sh, lexicographical > is undefined.
Um, ok, after a little fixing:
#!/bin/sh
temp=$(df -h | awk '$NF=="/"{$5}')
if [ "$temp" -gt 0 ] ; then
df -h | awk '$NF=="/" {printf("%s\n"),$5}'
(date -d "today" +"Date:%Y.%m.%d"" Hour: %H:%M")
fi
The [ ... ] command is the same as test command. Test does not have < comparison for numbers. It has -gt (greater then). See man test.
This will run now, but definitely not do what you want. You want the fifth column of df output, ie. the use percents. Why do you need -h/human readable output? We dont need that. Which row of df output do you want? I guess you don't want the header, ie. the first row: Filesystem 1K-blocks Used Available Use% Mounted on. Let's filter the columns with the disc name, I choose /dev/sda2. We can filter the row that has the first word equal to /dev/sda2 with grep "^/dev/sda2 ". The we need to get the value on the fifth column with awk '{print $5}'. We need to get rid of the '%' sign too, otherwise shell will not interpret the value as a number, with sed 's/%//' or better with tr -d '%'. Specifying date -d"today" is the same as just date. Enclosing a command in (...) runs it in subshell, we don't need that.
#!/bin/sh
temp=$(df | grep "^/dev/sda2 " | awk '{print $5}' | tr -d '%')
if [ "$temp" -gt 0 ]; then
echo "${temp}%"
date +"Date:%Y.%m.%d Hour: %H:%M"
fi
This is a simple, that if use percentage on disc /dev/sda2 is higher then 0, then it will print the use percentage and print current date and time in a custom format.
Assuming you're using GNU tools, you can narrow the df output to just what you need:
pct=$( df --output=pcent / | grep -o '[[:digit:]]\+' )
if [[ $pct -gt 60 ]]; then ...

Parsing timestamp using sed and embedded command

There's a file with some lines containing some text and either date or time stamp:
...
string1-20141001
string2-1414368000000
string3-1414454400000
...
I want to quickly convert time stamps to dates, like this:
$ date -d #1414368000 +"%Y%m%d"
20141027
and I want to do this dynamically with sed or some similar command line tool. For testing I unsuccessfully use this:
$ echo "something-1414454400000" | sed "s/-\(..........\)...$/-$(date -d #\\1 +'%Y%m%d')/"
date: invalid date '#\\1'
something-
but echoing seems to be working:
$ echo "something-1414454400000" | sed "s/-\(..........\)...$/-$(echo \\1)/"
something-1414454400
so what could be done?
It's interesting what's happening here. Some pointers:
Always single-quote your regex for sed, if possible, when using BASH (etc), especially if using special characters like$. This is why date is being run (with -d #\\1) before sed even gets involved.
Your "working" echo example isn't, actually (I believe): echo \\1 produces \1 (and as above, will do so before sed even gets invoked). This then happens to valid sed replacement syntax, so will substitute your group on the LHS, which is why the output looks about right.
Note that by using -r, you can use easier / more advanced regex syntax.
Hard to say exactly what to do without a bit more context, but to fix the immediate problems, try something like:
echo "something-1414454400000" | sed -re 's/-([0-9]{10,}).+/-$(date -d #\1 +"%Y%m%d")/'
which produces: $(date -d #1414454400) (which you can then pipe to sh)
Or for a more complete solution, you can change the regex to produce a shell command directly, and pipe it:
echo "something-1414454400000" | sed -re 's/(.*-)([0-9]{10,10}).+/echo \1$(date -d #\2 \"+%Y%M%d\")/' | sh
..producing something-20140028
You can do this in BASH:
while read -r p; do
if [[ "$p" =~ ^(.+-)([0-9]{10}).{3}$ ]]; then
echo -n "${BASH_REMATCH[1]}"
date -d "#${BASH_REMATCH[2]}" +"%Y%m%d"
else
echo "$p"
fi
done < file
OUTPUT:
string1-20141001
string2-20141026
string3-20141027
awk -F- 'BEGIN { OFS=FS }
$2 ~ /^[0-9]{13}$/ {
"date -d#" $2/1000 " +%Y%m%d " | getline t; $2=t }1'
Just try this command. I have checked it. It is working on your inputs.
cat file | sed -E "s,(.*)-(.*),\1-`date -d #1414368000 +'%Y%m%d'`,g"

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