Calculate number of days between 2 dates Unix Shell - bash

I want to calculate number of days between two dates in the unix shell .
I tried to do a minus calculation but it dosen’t work .
This is my script
VAR1=$1
VAR2=$2
v_date_deb=`echo ${VAR1#*=}`
v_date_fin=`echo ${VAR2#*=}`
dif = ($v_date_deb - $v_date_fin)
echo dif
if [ "$v_date_deb" = "" ]
then
echo "Il faut saisir la date debut.."
exit
fi
if [ "$v_date_fin" = "" ]
then
echo "Il faut saisir la date fin.."
exit
fi

One attempt (but shot in the dark, since we don't know what is in your VAR1 variables)
ts1=$(date -d "${VAR1#*=}" +"%s")
ts2=$(date -d "${VAR2#*=}" +"%s")
dt=$(( (ts2 - ts1) / 86400 ))
Note the remark from William Pursell above: this solution is dependent on your "date" version. Date is not a built-in command from bash. And, particularly, the -d option (that allows to use the date specified instead of the current date that date is supposed to use otherwise, when used in "print the date" mode) is not common to all "date".

Related

bash script error until [1: command not found

Can someone solve my headache with the following code. I want to write a bash script that will create a table that contain interval of time according to informations input by a user and display table. this is a part of another program but I got stack with this until command that is supposed to be easy to use. Sorry! I'm coding in French but the idea is as I explained
#!/bin/bash
read -p "entrez l'heure de depart(exple: hh:mn:06 or hh:mn:36):" beg_time
read -p "entrez l'intervalle de temps en minute(exple: 10):" Inter
read -p "entrez le nombre d'occurence(exple: 4):" Nbre
let "i = 1"
let "Nb = $Nbre"
tab=("$beg_time")
until [ "$i" -eq "$Nb" ]
do
tab["$i"]=`date -j -v '+"$Inter"M' -f "%H:%M:%S" "$beg_time" "+%T"`
let "i += 1"
done
echo ${tab[*]}
but I'm get this as error
line 8: until [ 1: command not found
I need to mention that I'm using a MacOS so the date command may not work on other linux OS. Please help
fix the variable assignments:
i=1
Nb="${Nbre}"
the same goes for let "i += 1"
Launching this on my mac I don't have the same error :
+"$Inter"M: Cannot apply date adjustment
I think you don't need to quote in your until statement, it's two numbers.
Are you using bash or zsh ?
I find the problem with until. for some reasons I needed to add a space after ]. then I also needed to do some small changes to my script.
the final update is as following.
#!/bin/sh
read -p "entrez l'heure de depart(exple: hh:mn:06 or hh:mn:36):" beg_time
read -p "entrez l'intervalle de temps en minute(exple: 10):" Inter
read -p "entrez le nombre d'occurence(exple: 4):" Nbre
let "i = 1"
let "Nb = $Nbre"
tab=("$beg_time")
until [ $Nb -eq $i ]
do
tab["$i"]=`date -j -v ""+$Inter"M" -f "%H:%M:%S" "$beg_time" "+%T"`
beg_time=${tab["$i"]}
let "i += 1"
done
echo ${tab[*]}
thank you for helping

Script to copy files for last month

I am trying to copy files using robocopy. The files I want to copy should be of last month(not one month old) i.e. on if I am running the script in the march month(any day) then it should copy all the files with timestamp of february. I am using below script:
robocopy source/*.prev destination maxage:20180201 minage:20180228
How to use the date as a variable here so I don't have to manually change it every month?
Having GNU date around you can do it this way:
start=$(date -d "$(date +%Y-%m-1) -1 month" +%Y%m%d)
end=(date -d "$(date +%Y-%m-1) -1 day" +%Y%m%d)
robocopy source/*.prev destination maxage:${start} minage:${end}
See linux - Using date command to get previous, current and next month
to see why we need -d. On 31st of a month the -1 month breaks otherwise.
The last date you can calculate like this: date -d "-$(date +%d) days -0 month" +%Y-%m-%d
which today outputs: 2018-02-28
The first date is a simple fixed start day: date -d "-$(date +%d) days -0 month" +%Y-%m-01
Which gaves when executed today: 2018-02-01
Your command could thus be:
robocopy source/*.prev destination \
maxage:$(date -d "-$(date +%d) days -0 month" +%Y%m01) \
minage:$(date -d "-$(date +%d) days -0 month" +%Y%m%d)
Edit: Since this is using GNU date syntax, this might not work on unix as stated by #ghoti
Let me assume POSIX compliant date is available.
Then how about:
#!/bin/bash
days[1]=31; days[2]=28; days[3]=31; days[4]=30
days[5]=31; days[6]=30; days[7]=31; days[8]=31
days[9]=30; days[10]=31; days[11]=30; days[12]=31
# current year and month
year=$(date +%Y)
month=$(( $(date +%m) + 0 ))
# previous month
if [[ "$month" = "1" ]]; then
year=$(( $year - 1 ))
month="12"
else
month=$(( $month - 1 ))
fi
days=${days[$month]}
# a leap year correction
if [[ "$month" = "2" ]]; then
days=$(( $days + ($year % 400 == 0 || ($year % 100 != 0 && $year % 4 == 0)) ))
fi
maxage=$( printf "%04d%02d%02d" $year $month 1 )
minage=$( printf "%04d%02d%02d" $year $month $days )
#echo off
setlocal enableextensions disabledelayedexpansion
rem Initialize variables to hold the previous month information
set "yyyy="
set "mm="
set "dd="
rem The robocopy in the for command will generate an error with the current date
for /f "tokens=1,2 delims=/" %%a in ('
robocopy "|" . /njh
') do if not defined yyyy (
rem Calculate previous month from current date
set /a "mm=(1%%b-90) %% 12 + 1", "yyyy=%%a - !(mm %% 12)"
rem Calculate the last day of the previous month
set /a "dd=30+((mm+mm/8) %% 2)+(-2+!(yyyy%%4)-!(yyyy%%100)+!(yyyy%%400))*!(%%b-3)"
rem Increase month and day for proper padding
set /a "dd+=100", "mm+=100"
)
rem Leave only the two right digits in month and day
set "mm=%mm:~-2%"
set "dd=%dd:~-2%"
rem Do the copy operation, selecting files from first to last days in previous month
robocopy "x:\source" "y:\target" *.prev /maxage:%yyyy%%mm%01 /minage:%yyyy%%mm%%dd%

Bash script: Use of date in foldername for calculation (Delete folders older than X)

We have backup foldernames like "db_YYYY-MM-DD".
Is there some kind of command/expression I could use to compare the folder's (name-)date to the current (system-)date and delete anything older than X days?
Background:
We already tried "find" and "-mtime +X" but modification time is not a perfect solution because it updates when you modify/delete files inside the folders afterwards..
It is a rare condition but makes the -mtime comparison "faulty", so I look for an alternative and the folder's name doesn't change ever during creation/backup/modification..
You can use following way to generate the folder name
#foldername="db_"`date "+%Y-%m-%d"`
#echo $foldername
db_2017-08-15
#mkdir $foldername
Now you can compare like string with given date
so 7 days older date will be
givenDate="db_"`date -v-7d "+%Y-%m-%d"`
if ($foldername > $givenDate)
True if foldername sorts after givenDate lexicographically.
The good thing about the YYYY-MM-DD date format is that the dictionary comparison order matches the time order. Therefore you can simply extract the backup date from your directory name and compare it as a string with the corresponding date in the same format:
backupdirname=db_2017-08-12
X=6
backupdate="${backupdirname: -10}"
dropdate="$(date -d "$X days ago" +%Y-%m-%d)"
if [[ "$backupdate" < "$dropdate" ]]
then
echo "Delete $backupdirname"
else
echo "Keep $backupdirname"
fi
ref_date=$(date -d '2017-01-02' +%s)
for file in ./db_*; do
file_time=$(date -d ${file#*db_} +%s)
if [[ $file_time > $ref_date ]]; then
echo "$file date is newer than ref date"
# ...
else
echo "$file date is older or euqal to ref date"
# ...
fi
done

BASH script checking log files for current and previous month

I have been working on this on and off for the last two months, and despite how many times I look at it, I can't make it work.
This script checks daily log files for a user defined variable, so they don't have to look through every one manually. It worked great checking the current month, but if the user wants to check back 20 days, and today is the 12th of this month, I wanted to be able to then go back to the previous month (not look for the log file with a date of 20150399 and so on). I have checked the logic for my date/day computations, and they seem okay (if there is a better way to do that in BASH, I am open to suggestions). What happens when I try to debug is unexpected end of file. I am somewhat new to writing scripts that contain more than 20 or so lines, but I just can't come up with what I am missing.
I have tried various fixes, to no avail, but I think this is the last iteration.
Ideas?
#!/bin/bash
########################################################
# multi_log_chk.sh
# This script will take input from the user and report which
# CyberFusion MFT logs contain what the user is looking for.
# Hopefully this will save the user having to search through every
# stinking log file to find what they are looking for.
# 20150406 pxg007 started typing
# 20150413 pxg007 added && comparison for back out (line 28)
# added message for no entries found (line 32, 38, 48-52)
# Added some further description (line 16)
# 20150424 pxg007 Added logic to calculate previous month and if necessary, year. (Lines 16-24, 60-78 )
#
########################################################
currDate=`date +%d%B%C%y`
currDay=`date +%d`
currMnth=`date +%m`
currYear=`date +%C%y`
case $currMnth in #Let's establish number of days for previous month
05 | 07 | 10 | 12 ) lastMnthD=30;;
01 |02 | 04 | 06 | 09 | 08 | 11 ) lastMnthD=31;;
03 ) lastMnthD=28;; ##and screw leap year
esac
if [ $currMnth -eq 01 ]; then ##accounting for January
lastMnth=12
else
lastMnth=$((currMnth-1))
fi
if [ $lastMnth -eq 12 ]; then ## accounting for Dec of previous year
lastMnthYr=$((currYear-1))
else
lastMnthYr=$currYear
fi
echo "This script will find entries for your query in whatever available MFT logs you request."
echo " "
echo "For instance - how many log files have transfer entries with \"DOG\" in them?"
echo " "
echo "I also will also give an estimate of how many transfers per log file contain your query, give or take a couple."
echo " "
echo "This search is case sensitive, so \"DOG\" is *** NOT *** the same as \"dog\""
echo " "
read -p "What text you are looking for? Punctuation is okay, but no spaces please. " looking ### what we want to find
echo " "
echo "Today's date is: $currDate."
echo " "
read -p "How many days back do you want to search(up to 25)? " daysBack ### How far back we are going to look
if [ "$daysBack" == 0 ] && [ "$daysBack" >> 25 ]; then
echo "I said up to 25 days. We ain't got more than that!"
exit 1
fi
echo " "
echo "I am going to search through the last $daysBack days of log files for:\"$looking\" "
echo " "
read -p "Does this look right? Press N to quit, or any other key to continue: " affirm
if [ "$affirm" = N ] && [ "$affirm" = n ]; then ###Yes, anything other than "N" or "n" is a go
echo "Quitter!"
exit 1
else
nada=0 ### Used to test for finding anything
backDate=$((currDay-daysBack)) ### current month iterator (assuming query covers only current month)
if (("$daysBack" => "$currDay")); then ## If there are more logs requested than days in the month...
lastMnthCnt=$((daysBack-currDay)) ### how many days to check last month
lastMnthStrt=$((lastMnthD-lastMnthCnt)) ## last month start and iterator
backDate=$(currDay-(daysBack-lastMnthCnt)) # Setting the iterator if we have to go back a month
while (("$lastMnthStrt" <= "$lastMnthD" )); do
foundIt=$(grep "$looking" /CyberFusion/log/Log.txt."$lastMnthYr$lastMnth$lastMnthStrt" | parsecflog | wc -l )
howMany=$((foundIt/40+1)) ### Add one in case there are less than 40 lines in the record.
if (("$foundIt" > 0))
then
nada=$((nada+1))
echo "Log.txt.$lastMnthYr$lastMnth$lastMnthStrt contains $looking in approximately $howMany transfer records."
lastMnthStrt=$((lastMnthStrt+1))
echo " "
else
lastMnthStrt=$((lastMnthStrt+1))
fi
fi
backDate=$((currDay-daysBack)) ### current month iterator (assuming query covers only current month)
while (("$backDate" <= "$currDay")); do
foundIt=$(grep "$looking" /CyberFusion/log/Log.txt."$backDate" | parsecflog | wc -l )
howMany=$((foundIt/40+1)) ### Add one in case there are less than 40 lines in the record.
if (("$foundIt" > 0))
then
nada=$((nada+1))
echo "Log.txt.$backDate contains $looking in approximately $howMany transfer records."
backDate=$((backDate+1))
echo " "
else
backDate=$((backDate+1))
fi
if [ "$nada" \< 1 ]
then
echo " "
echo "I found no entries for $looking in any log file."
fi
You are missing the keyword 'done' on lines 81 and 96 and also a final 'fi' keyword on the last line.
Also as others suggested you can do
date -d "20 days ago" +"%d%B%C%y"
to easily get dates in the past

Arithmetic operation on time variable in c-shell

I need help using time in the c-shell
I want to know how much time it took to execute a script,so i want to do in the following way
1.set start_time=time
2 script part
3.set end_time=time
4. set diff=end_time-start_time
5.echo "It took $diff seconds"
but i couldn't get the time value using any command.
could any one suggest a command to read the time value in c-shell
I think you want the "date" command, with the format to give you raw seconds:
# start_time = `date +%s`
script part
# end_time = `date +%s`
# diff = $end_time - $start_time
echo "It took $diff seconds"

Resources