How to subtract today's date with a file's modification date in unix? - bash

For example:
echo $(date) - $(date -r sample.txt)
Output:
90 days(for example)

Use %s seconds since 1970-01-01 00:00:00 UTC as in
echo $(expr $(date +%s) - $(date -r sample.txt +%s)) #!/bin/sh
echo $(($(date +%s) - $(date -r sample.txt +%s))) #/bin/bash

One more way
$ ls -l peter.txt
-rwxrw-r--+ 1 pppp qqqq 149 Dec 15 18:39 peter.txt
$ echo "(" $(date +%s) - $(date -r peter.txt +%s) ")/" 86400 | perl -nle ' print eval, " days" '
29.254537037037 days
$

Related

How to get second sunday in a Month given a date parameter in bash script

I am trying to write a bash script, to merge 24 files in a given day. The requirement changes during Day light saving time changes, where I get 23 or 25 files.
So, with further research I realized that day-light savings begins on the second Sunday of March(23) of every year and ends on first sunday of Novemeber(25).
I need more inputs to get second sunday in a given month to do the check of finding 23 or 25 files for March and November respectively.
Any inputs to help me with this will be really appreciated.
Thank you
Here is the sample code to find 24 files in a day-
if [ -z "$1" ];then
now=$(date -d "-1 days" +%Y-%m-%d);
else now=$1;
fi
load_date='load_date='$now
singlePath="$newPath/$load_date"
fileCount=$(hdfs dfs -ls -R $hdfsPath/$load_date/ | grep -E '^-' | wc -l)
path=$hdfsPath/$load_date
if [ $fileCount -eq 24 ]; then
echo "All files are available for "$load_date;
hadoop fs -cat $path/* | hadoop fs -put - $singlePath/messages.txt
else echo $fileCount" files are available for "$load_date"! Please note, few files are being missed";
fi
I wouldn't hardcode the dates of DST transistions. I would just count "how many hours did today have":
a "normal" day:
$ diff=$(( $(date -d now +%s) - $(date -d yesterday +%s) ))
$ echo $(( diff / 3600 ))
24
"spring forward"
$ diff=$(( $(date -d "2019-03-10 23:59:59" +%s) - $(date -d "2019-03-09 23:59:59" +%s) ))
$ echo $(( diff / 3600 ))
23
"fall back"
$ diff=$(( $(date -d "2019-11-03 23:59:59" +%s) - $(date -d "2019-11-02 23:59:59" +%s) ))
$ echo $(( diff / 3600 ))
25
One thing to note: since bash only does integer arithmetic, if the difference is not 86400 but 86399, you get:
$ echo $((86399 / 3600))
23
So, better to query yesterday's time first in the tiny-but-non-zero chance that the seconds tick over between the 2 date calls:
diff=$(( -$(date -d yesterday +%s) + $(date -d now +%s) ))
Here, $diff will be 86400 or 86401 (for non DST transition days), and dividing by 3600 will give 24 not 23.

Error on backup bash script: syntax error near unexpected token `newline'

I am having problem finding error on bash script for handling backup:daily, monthly, yearly. Here is the script:
#!/bin/bash
echo > /home/alpha/folder/keep.txt
#writing dates of the backups that should be kept to the array
for i in {0..7}; do ((keep[$(date +%Y%m%d -d "-$i day")]++)); done
for i in {0..4}; do ((keep[$(date +%Y%m%d -d "sunday-$((i+1)) week")]++)); done
for i in {0..12}; do
DW=$(($(date +%-W)-$(date -d $(date -d "$(date +%Y-%m-15) -$i month" +%Y-%m-01) +%-W)))
for (( AY=$(date -d "$(date +%Y-%m-15) -$i month" +%Y); AY < $(date +%Y); AY++ )); do
((DW+=$(date -d $AY-12-31 +%W)))
done
((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++))
done
for i in {0..30}; do
DW=$(date +%-W)
for (( AY=$(($(date +%Y)-i)); AY < $(date +%Y); AY++ )); do
((DW+=$(date -d $AY-12-31 +%W)))
done
((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++))
done
#writing the array to file keep.txt line by line
for i in ${!keep[#]}; do echo $i >> /home/alpha/folder/keep.txt; done
#delete all files that not mentioned in keep.txt
cd /home/alpha/folder
ls -1 /home/alpha/folder/ | sort /home/alpha/folder/keep.txt /home/alpha/folder/keep.txt - | uniq -u | xargs rm -rf
rm /home/alpha/folder/keep.txt
When I try to run the script, throws error message:
./back.sh: line 12: syntax error near unexpected token `newline' ./back.sh: line 12: ` done'
Where did I do wrong on the script?
Your date expression seems to misbehave inside the arithmetic context. Adding temporary variables solved your issue for me :
#!/bin/bash
echo > /home/alpha/folder/keep.txt
#writing dates of the backups that should be kept to the array
for i in {0..7}; do ((keep[$(date +%Y%m%d -d "-$i day")]++)); done
for i in {0..4}; do ((keep[$(date +%Y%m%d -d "sunday-$((i+1)) week")]++)); done
for i in {0..12}; do
DW=$(($(date +%-W)-$(date -d $(date -d "$(date +%Y-%m-15) -$i month" +%Y-%m-01) +%-W)))
begin=$(date -d "$(date +%Y-%m-15) -$i month" +%Y)
for (( AY=begin; AY < $(date +%Y); AY++ )); do
((DW+=$(date -d $AY-12-31 +%W)))
done
((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++))
done
for i in {0..30}; do
DW=$(date +%-W)
begin=$(($(date +%Y)-i))
for (( AY=begin; AY < $(date +%Y); AY++ )); do
((DW+=$(date -d $AY-12-31 +%W)))
done
((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++))
done
#writing the array to file keep.txt line by line
for i in ${!keep[#]}; do echo $i >> /home/alpha/folder/keep.txt; done
#delete all files that not mentioned in keep.txt
cd /home/alpha/folder
ls -1 /home/alpha/folder/ | sort /home/alpha/folder/keep.txt /home/alpha/folder/keep.txt - | uniq -u | xargs rm -rf
rm /home/alpha/folder/keep.txt
However, I am unsure why the expression misbehaves inside the arithmetic block.

change time output in bash script

How to change this time output ?
date --date="#$(echo $(TZ=UTC date +%s) - $(date +%s)'%(5*60)-(5*60)' | bc)"
Output: za apr 12 00:25:00 CEST 2014
Should output in this layout: %Y%m%d%H%M
How to implement this in the string ?
Thanks!!
i think this should do what you want:
d="#$(echo $(TZ=UTC date +%s) - $(date +%s)'%(5*60)-(5*60)' | bc)"&&echo `date --date="$d"` `date --date="$d" +%Y%m%d%H%M`
d="#$(echo $(TZ=UTC date +%s) - $(date +%s)'%(5*60)-(5*60)' | bc)"&&echo `date --date="$d" --utc` `date --date="$d" +%Y%m%d%H%M --utc`
Second one is in UTC.

How to compare the current date with past 60 days using shell script

start_time=`sed -e 's/\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\).*/\1/' <<< "$line"`
start_time_sec=`date -d "$start_time" +%s`
now=`date +%s`
pass_time=`$now - $start_time_sec`
if [ $pass_time <=86400*60 ]
then
initial_time= $start_time
initial_time_sec=`date -d "$initial_time" +%s`
break
fi
/Here I have tried with date comparison with seconds, But I want in terms of days/
ISO dates (YYYY-MM-DD) can be compared like strings:
$ date +%Y-%m-%d
2014-01-07
$ date +%Y-%m-%d -d '-60 days'
2013-11-08
$ [[ "$(date +%Y-%m-%d -d '-60 days')" < "$(date +%Y-%m-%d)" ]]
$ echo $?
0
start_time=`echo $line | sed -e 's/^\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\).*/\1/'`
start_time_sec=`date -d "$start_time" +%s`
now=`date +%s`
pass_time=`expr $now - $start_time_sec`
limit_time=$((60 * 60 * 24 * 60))
if [[ $pass_time -le $limit_time ]]; then
echo "in 60 days"
fi
update:
or your idea:
start_time_date=`date -d "$start_time" +%s`
past_date=`date +"%Y-%m-%d" -d "-60 day"`
if [[ $past_date -le $start_time_date ]]; then
echo 'in 60 days'
fi

Shell script to get difference between two dates

If there are dates as 2010-06-01 and another as 2010-05-15
Using shell script or date command how to get the number of days between the two dates
Thanks..
Using only date and shell arithmetics:
echo $((($(date -d "2010-06-01" "+%s") - $(date -d "2010-05-15" "+%s")) / 86400))
There's a solution that almost works: use the %s date format of GNU date, which prints the number of seconds since 1970-01-01 00:00. These can be subtracted to find the time difference between two dates.
echo $(( ($(date -d 2010-06-01 +%s) - $(date -d 2010-05-15 +%s)) / 86400))
But the following displays 0 in some locations:
echo $((($(date -d 2010-03-29 +%s) - $(date -d 2010-03-28 +%s)) / 86400))
Because of daylight savings time, there are only 23 hours between those times. You need to add at least one hour (and at most 23) to be safe.
echo $((($(date -d 2010-03-29 +%s) - $(date -d 2010-03-28 +%s) + 43200) / 86400))
Or you can tell date to work in a timezone without DST.
echo $((($(date -u -d 2010-03-29 +%s) - $(date -u -d 2010-03-28 +%s)) / 86400))
(POSIX says to call the reference timezone is UTC, but it also says not to count leap seconds, so the number of seconds in a day is always exactly 86400 in a GMT+xx timezone.)
OSX date is different than GNU date. Got it working like this in OSX. This is not portable solution.
start_date=$(date -j -f "%Y-%m-%d" "2010-05-15" "+%s")
end_date=$(date -j -f "%Y-%m-%d" "2010-06-01" "+%s")
echo $(( ($end_date - $start_date) / (60 * 60 * 24) ))
Idea is still same as in the other answers. Convert dates to epoch time, subtract and convert result to days.
Got it
d1=`date +%s -d $1`
d2=`date +%s -d $2`
((diff_sec=d2-d1))
echo - | awk -v SECS=$diff_sec '{printf "Number of days : %d",SECS/(60*60*24)}'
thanks..
Gnu date knows %j to display the day in year:
echo $(($(date -d 2010-06-01 +%j) - $(date -d 2010-05-15 +%j)))
crossing year-boundaries will give wrong results, but since you gave fixed dates ...

Resources