I'm trying to calculate the date for a dynamic number of days ago in a bash script.
This is what I've done -
#!/bin/bash
STAMP=`date --date='$1 day ago' +%y%m%d`
but when running myscript 2, it says -
date: invalid date `$1 day ago'
How can I use my argument value in this formula?
It works if ' is replaced with " into this command on the script -
STAMP=`date --date="$1 day ago" +%y%m%d`
The clue was the two different character ` and ' used in the error response -
date: invalid date `$1 day ago'
An expert in bash scripting (not me) can probably explain why this has happen.
It's because variable substitution wouldn't happen in single quotes, i.e. '$1' wouldn't expand but "$1" would.
As such, saying
STAMP=`date --date="$1 day ago" +%y%m%d`
or
STAMP=$(date --date="$1 day ago" +%y%m%d)
would work.
Related
We have a system that would have a cron job that deletes files up to two months ago. I'm trying to write a script to automate this, but I'm fairly new to bash scripting and was wondering if anyone would be able to help. Our files are in %m%Y format and I would be moving them to another directory and then deleting that directory. So for instance since we are in August (082020), I want to move all files up to June (062020) starting this year in Jan (012020).
Here is my script so far, I am basically just trying to print 012020-062020, can anyone let me know if I am on the right track?
#!/bin/bash
MONTHYEAR=$(date +%m%Y)
DELUPTO=$(expr $(date +%m%Y) - 20000)
CURRENTYEAR=$(date +%Y)
for (( i=$DELUPTO; i>=01 + $CURRENTYEAR; $(expr $i - 10000) ))
do
echo "$i"
done
You should loop from the format yyyydd, so start with
for (( i=202006; i>=202001; i-- )); do
echo "${i:4:2}${i:0:4}"
done
It is up to you how you want to achieve this:
yearmonth=$(date +%Y%m)
or
MONTHYEAR=$(date +%m%Y)
yearmonth=${MONTHYEAR:2:4}${MONTHYEAR:0:2}
You know the month and year, extract those values and then turn it into a stamp, but you will need to insert a day value so I would make it say the 1st:
Example of converting timestamps:
# date -d "8/1/2020" +"%s"
1596254400
# date -d #1596254400 +"%b %d %Y %H:%M:%S"
Aug 01 2020 00:00:00
Then create a time stamp of now minutes X days:
date +%s -d "60 days ago"
Once you have common values to compare, Then compare them and if less than 60 days delete Pseudo code:
del_date=$(date +%s -d "60 days ago")
for each file in directory:
#get month and day from file name here, then
file_date=$(date -d "${fmonth}/1/${fyear}" +"%s")
if [[ $file_date -lt $del_date ]] ;then
echo "Older than 60 days by name"
fi
done
Note: It would probably be better to delete files by checking their ages in the system using stat command opposed to reading the details of file name.
I'm currently creating a shell script that will run a python code once an hour that collects, processes, and displays data from a radar for the previous hour.
The python code I am using requires a UTC begin time and end time in format "YYYYMMDDHHmm". So far, I have found using the unix command date -u +"%Y%m%d%H%M" will retrieve my current time in the correct format, but I have not been able to find a way to subtract 60 minutes from this first time and have it output the "start" time/
code I have tried:
date +"%Y%m%d%H%M-60" >> out: 201908201833-60
now= date -u +"%Y%m%d%H%M" >> out:201908201834
echo "$now - 60" >> out: - 60
I'm just starting to self teach/learn shell coding and I am more comfortable with python coding which is why my attempts are set up more like how you would write with python. I'm sure there is a way to store the variable and have it subtract 60 from the end time, but I have not been able to find a good online source for this (both on here and via Google).
You can use -d option in date:
date -u +"%Y%m%d%H%M" -d '-60 minutes'
or else subtract 1 hour instead of 60 minutes:
date -u +"%Y%m%d%H%M" -d '-1 hour'
To be able to capture this value in a variable, use command substitution:
now=$(date -u +"%Y%m%d%H%M" -d '-1 hour')
On OSX (BSD) use this date command as -d is not supported:
now=$(date -u -v-1H +"%Y%m%d%H%M")
Your current attempt has some simple shell script errors.
now= date -u +"%Y%m%d%H%M" >> out:201908201834
This assigns an empty string to the variable now and then runs the date command as previously. If the plan is to capture the output to the variable now, the syntax for that is
now=$(date -u +"%Y%m%d%H%M")
Next up, you try to
echo "$now - 60"
which of course will output the literal string
201908201834 - 60
rather than perform arithmetic evaluation. You can say
echo "$((now - 60))"
to subtract 60 from the value and echo that -- but of course, date arithmetic isn't that simple; subtracting 60 from 201908210012 will not produce 201908202312 like you would hope.
If you have GNU date (that's a big if if you really want to target any Unix) you could simply have done
date -u -d "60 minutes ago" +%F%H%M
but if you are doing this from Python anyway, performing the date extraction and manipulation in Python too will be a lot more efficient as well as more portable.
from datetime import datetime, timedelta
dt = datetime.strptime(when,'%Y%m%d%H%M')
print(dt - timedelta(minutes=60))
The shell command substitution $(command) and arithmetic evaluation $((expression)) syntaxes look vaguely similar, but are really unrelated. Both of them have been introduced after the fundamental shell syntax was already stable, so they had to find a way to introduce new syntax which didn't already have a well-established meaning in the original Bourne shell.
A few months ago I wrote a some bash to get dates. I needed these dates as facts in an ansible script to later use them to get data from the database. This worked fine until today here is the code:
- name: Set date variables
set_fact:
first_day_last_month: "{{lookup('pipe','date -d \"-1 month -$(($(date +%d)-1)) days\" +%Y-%m-%d')}}"
last_day_last_month: "{{lookup('pipe','date -d \"$(date +%Y-%m-01) -1 day\" +%Y-%m-%d')}}"
first_day_current_month: "{{lookup('pipe','date -d \"-$(($(date +%d)-1)) days\" +%Y-%m-%d')}}"
last_day_current_month: "{{lookup('pipe','date -d \"-$(date +%d) days +1 month\" +%Y-%m-%d')}}"
However when I run this now I get an error:
/bin/sh: 1: arithmetic expression: expecting EOF: "08-1"
I tried debugging it on the bash command line:
seven#monstermachine:~$ echo $(date -d "-$($(date +%d)-1)")
08-1: command not found
Mit Nov 8 00:00:00 CET 2017
but until now i'm not getting it fixed.
Anyone have any idea?
%d is zero padded which gives base eight or octal number and 08 is not a valid octal number which thows an error.
What you need is something like :
echo $(date -d "$(($(date +%e)-1))")
Wed Nov 8 07:00:00 IST 2017
Note %e will cause date to be space padded which is equivalent to %_d.
To perform a mathematical expression use $(( expression )) format. I didn't understand the actual logic behind your code, so make sure your code fits the logic.
To get first_day_current_month in your script, you could use:
date +%Y-%m-01
similar for the others, for example to get last_day_last_month:
date -d `date +%Y-%m-01`"-1 day" +%Y-%m-%d
Thanks for the help I will make use of both of your answers to come up with a better working command.
I want to write a bash script that will run on a given but process data with next days date, My current approach is to get the unix time stamp and add a days worth of seconds to it, but I cant get it working, and haven't yet found what I'm looking for online.
Here's what I've tried, I feel like the problem is that its a string an not a number, but I dont know enough about bash to be sure, is this correct? and how do I resolve this?
today="$(date +'%s')"
tomorrow="$($today + 86400)"
echo "$today"
echo "$tomorrow"
If you have gnu-date then to get next day you can just do:
date -d '+1 day'
Some of the answers for this question depend on having GNU date installed. If you don't have GNU date, you can use the built-in date command with the -v option.
The command
$ date -v+1d
returns tomorrow's date.
You can use it with all the standard date formatting options, so
$ date -v+1d +%Y-%m-%d
returns tomorrow's date in the format YYYY-MM-DD.
$(...) is command substitution. You're trying to run $today + 86400 as a command.
$((...)) is arithmetic expansion. This is what you want to use.
tomorrow=$(( today + 86400 ))
Also see http://mywiki.wooledge.org/ArithmeticExpression for more on doing arithmetics in the shell.
I hope that this will solve your problem here.
date --date 'next day'
Set your timezone, then run date.
E.g.
TZ=UTC-24 date
Alternatively, I'd use perl:
perl -e 'print localtime(time+84600)."\n"'
echo $(date --date="next day" +%Y%m%d)
This will output
20170623
I like
input_date=$(date '+%Y-%m-%d')
tomorrow_date=$(date '+%Y-%m-%d' -d "$input_date + 1 day")
echo "$tomorrow_date"
It returns the date of the day after $input_date, in format YYYY-MM-DD
You can try below
#!/bin/bash
today=`date`
tomorrow=`date --date="next day"`
echo "$today"
echo "$tomorrow"
I have a bash script and I need it to fulfill some conditions if it is 1st day of month.
I have written this code
ifStart=`date '+%d'`
if [$ifStart == 01]
then
test=`/bin/date --date='1 day ago' +'%Y-%m'`
echo $test
fi
I expect it to show 2013-03 today, but I get an errormessage:
Line 2 command not found.
test=`/bin/date --date='1 day ago' +'%Y-%m'`
this part works well without if.
Any suggestions?
The command that's not being found is actually due to your if statement. You need spaces:
if [ $ifStart == 01 ]
Otherwise [$ifStart will be interpreted as a command.