Logical AND in shell script while loop - shell

I am trying to compare dates in the while loop of a shell script. The shell script will be controlled by 2 conditions, like the following:
while [ $currentDate -le $currentDateMonthEnd -a $currentDate -le $toDate ]; do
...
done
The above is my current code, which complains of "integer expression expected". I have also tried using && and AND, which also do not work and complains of mismatching braces.
Could someone please provide the syntax to make the above comparison?

dc ()
{
[ $(date +%s -d "$1") $2 $(date +%s -d "$3") ]
}
while dc "$currentDate" -le "$currentDateMonthEnd" && dc "$currentDate" -le "$toDate"
do
# ...
done

following code works for me,
#! /bin/bash
toDate=`echo 2014/03/30 | tr -d "/"`
currentDate=`date +"%Y/%m/%d" | tr -d "/"`
currentDateMonthEnd=`date +%Y/%m/%d -d "-$(date +%d) days +1 month" | tr -d "/"`
while [[ $currentDate -le $currentDateMonthEnd ]] && [[ $currentDate -le $toDate ]]
do
...
done
#! /bin/sh
while [ $currentDate -le $currentDateMonthEnd ] && [ $currentDate -le $toDate ]
do
...
done

Related

Printing date range in AIX

I'm trying to print date range in AIX. I'm not able to use 'date' in AIX properly. I've tried some solutions suggested in Stack overflow. Nothing worked. Please find the error and code below.
I can't download 'GNU'.
#!/bin/ksh
startdate=20141030
enddate=20141120
loop_date=$startdate
let j=0
while [ "$loop_date" -ne "$enddate" ]; do
loop_date=`date -j -v+${j}d -f "%Y%m%d" "$startdate" +"%Y%m%d"`
echo $loop_date
let j=j+1
done
Error:
date: illegal option -- j
Usage: date [-u] [+Field Descriptors]
Try this;
#!/bin/ksh
startdate=$1
enddate=$2
loop_date=$startdate
currentdate=`date +%Y%m%d`
let j=0;
if [[ $startdate -lt $currentdate && $enddate -lt $currentdate ]];then
loop_date=$currentdate
while [[ "$loop_date" -gt "$startdate" ]]; do
loop_date=$(TZ=CST+$j date +%Y%m%d)
if [[ $loop_date -le $enddate ]];then
echo $loop_date
fi
let j=j+24
done
fi
if [[ $startdate -gt $currentdate && $enddate -gt $currentdate ]];then
while [[ "$loop_date" -lt "$enddate" ]]; do
loop_date=$(TZ=CST-$j date +%Y%m%d)
if [[ $startdate -le $loop_date ]];then
echo $loop_date
fi
let j=j+24
done
fi
user#host:/tmp:>ksh test.sh 20150630 20150705
20150705
20150704
20150703
20150702
20150701
20150630
user#host:/tmp:>ksh test.sh 20170630 20170705
20170630
20170701
20170702
20170703
20170704
20170705

Error Converting String to Date in Shell

Hi I get the below error when I try to execute the below code:
date_input= '2015-01-25'
date_parameter=$(date -d `echo $date_input` +%s)
min_date=$(date -d 2015-11-01 +%s)
max_date=$(date -d $(date +"%Y-%m-%d") +%s)
if [ "$date_parameter" -gt "$max_date" ] || [ "$date_parameter" -lt "$min_date" ]; then
Error -> [: : integer expression expected
You can fix your script by using:
date_input='2015-01-25'
date_parameter=$(date -d "$date_input" '+%s')
min_date=$(date -d 2015-11-01 '+%s')
max_date=$(date '+%s')
[[ $date_parameter -gt $max_date || $date_parameter -lt $min_date ]] &&
echo "ok" || echo "nope"
Remove whitespace after = in first line.

Bash several and in if

Hi I have a csv file with dates like this which I want to parse with bash and check against todays date.
12-Jan-2015
Checking only day and month works good
DAT=$(date '+%d %b %Y')
DAY=${DAT:0:2}
MON=$(echo ${DAT:3:3} | awk '{print toupper("$0");}')
YEAR=${DAT:6:5}
while IFS=",-" read name day month year
do
day=$(printf "%02d\n" "$day")
month=$(echo "$month" | awk '{print toupper($0);}')
year=$(printf "%04d\n" "$year")
if [ "$day" -eq "$DAY" ] && [ "$month" = "$MON" ]; then
echo "$name";
fi
done < $SNAPDB > $SNAPTMPDB
but when I try to also check the year
if [ "$day" -eq "$DAY" ] && [ "$month" = "$MON" ] && [ "$year" -eq "$YEAR" ]; then
Script ends with an error: line 119: 2015: command not found
I´ve by now tried several writings like [[ … ]] -a and so on. but nothing did work.
Thanks for help!
Use -a for 'and' and -o for 'or'. From the documentation: http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html (look specifically at Table 7-2)
Updated from comments:
Use double brackets and parentheses:
if ( [[ "$day" -eq "$DAY" ]] && [[ "$month" = "$MON" ]] && [[ "$year" -eq "$YEAR" ]] ); then`

Bash Script for deleting old backup files

every night my server creates backups for every mysql database. All of these files are saved in a folder like /backup/mysql/2014-11-28. Over the last few months a lot of folders and files have been stored in that directory and I would like to reduce this.
Therefore I would need a bash script which deletes every folder in the given directory, except every folder created this month (not in the last 30 days, but the actual month) and except one backup from every week (for example the backup from sunday). Since I have no clue how to do the sunday party I decided it would be simpler to keep the backups from the 07th, the 14th, the 21st and the the 28th.
#!/bin/bash
in_array() {
local haystack=${1}[#]
local needle=${2}
for i in ${!haystack}; do
if [[ ${i} == ${needle} ]]; then
return 0
fi
done
return 1
}
YEAR=`date +%Y`
LASTYEAR=`date +%Y -d "1 year ago"`
MONTH=`date +%m`
DAYS="07 14 21 28"
for i in $( ls ); do
BACKUP_YEAR=$(echo "${i}" | cut -d'-' -f1)
BACKUP_MONTH=$(echo "${i}" | cut -d'-' -f2)
BACKUP_DAY=$(echo "${i}" | cut -d'-' -f3)
DELETE=false
if [[ "$BACKUP_YEAR" == "$YEAR" ]]; then
if [[ "$BACKUP_MONTH" != "$MONTH" ]]; then
if [ $(in_array $DAYS "$BACKUP_DAY") ]; then
DELETE=true
fi
fi
fi
if [[ "$BACKUP_YEAR" == "$LASTYEAR" ]]; then
if [[ "$BACKUP_DAY" != ${DAYS[0]} ]]; then
DELETE=true
fi
fi
if [ "$DELETE" = true ] ; then
#OUTPUT=`rm -v -R $i`
echo $i
fi
done
The second part (backups from the year before) works perfectly fine, but the first part (for backups from this year) doesn't work and I don't know why. I found the function on this site, but I guess somehow my call is wrong.
EDIT: The code I am now using:
#!/bin/bash
read YEAR MONTH <<<$(date "+%Y %m")
LASTYEAR=$(( YEAR-1 ))
DAYS=" 07 14 21 28 "
for fn in $( ls )
do
if ([ "${fn:0:4}" = "$YEAR" ] &&
[ "${fn:5:2}" != "$MONTH" ] &&
[ "${DAYS/ ${fn:8:2} /}" = "$DAYS" ]) || ([ "${fn:0:4}" = "$LASTYEAR" ] &&
[ "${fn:8:2}" != ${DAYS:1:2} ])
then
#OUTPUT=`rm -v -R $fn`
echo "$fn"
fi
done
#!/bin/bash
read YEAR MONTH <<<$(date "+%Y %m")
LASTYEAR=$(( YEAR-1 ))
DAYS=" 07 14 21 28 "
for fn in $( ls )
do
DELETE=false
if [ "${fn:0:7}" = "$YEAR-$MONTH" ] &&
[ "${DAYS/ ${fn:8:2} /}" != "$DAYS" ]
then
DELETE=true
elif [ "${fn:0:4}" = "$LASTYEAR" ] &&
[ "${fn:8:2}" != ${DAYS:1:2} ]
then
DELETE=true
fi
if [ "$DELETE" = true ]
then
#OUTPUT=`rm -v -R $fn`
echo "$fn"
fi
done
Assuming that a file name matches the following date format YYYY-MM-DD, for instance, 2014-03-27, the expression ${fn:0:7} would be 2014-03; ${fn:8:2} would be 27; ${fn:0:4} would be 2014.
Read the bash manual pages about the parameter expansion.
The expression ${DAYS/ ${fn:8:2} /} checks the day from the filename (wrapped by white spaces) is found in the DAYS list. It would be equivalent to echo "${DAYS}" | grep -q "${BACKUP_DAY}".
note: it is possible to reduce the commands inside the for loop (join if and elif by means of a || and remove the DELETE variable checking and the DELETE variable itself) but I decided to keep the look of the original script.

How to use korn shell get the first/last day of previous month

my ksh version is not allowed date -d.
The bellow code has problem when current month is January.
#!/bin/ksh
yy=`date +%Y`
mm=`date +%m-1|bc`
[ $mm -lt 1 ] && (mm=12;yy=`expr $yy - 1`)
[ $mm -le 9 ] && mm="0$mm"
getcal=`cal $mm $yy`
last_dd=`echo $getcal|awk '{print $NF}'`
dd1=`echo $getcal|awk '{print $10}'`
first_dd="0$dd1"
echo $yy$mm$last_day
echo $yy$mm$first_day
You're using a subshell: any variable changes you make will not survive the subshell exiting:
$ m=5; (m=10); echo $m
5
Use a different grouping construct
[ $mm -lt 1 ] && { mm=12; ((yy -= 1)); }
If you have GNU date, you can do:
$ first_of_this_month=$(date "+%Y-%m-01")
$ date -d "$first_of_this_month - 1 day" "+%Y-%m-%d"
2014-03-31
$ date -d "$first_of_this_month - 1 month" "+%Y-%m-%d"
2014-03-01

Resources