我正在编写一个备份脚本,我需要找到每个月的最后一个星期六。
我尝试过不同的方法来找到这一天,这本身就很出色。
问题是,当我尝试将它们放入我的脚本时,我总是得到错误代码
./test.sh: line 13: [: 29: integer expression expected
。
这是我的代码:
#!/bin/bash
LASTSAT=$(ncal | grep Sa | awk '{print$(NF-0)}')
SATURDAY="6"
DAY=$(date +"%u")
DATE=$(date +"%d")
echo "$DAY"
echo "$DATE"
echo "$LASTSAT"
if [ $DATE -eq $LASTSAT ]
then
echo "sista lördagen..."
fi
我得到了将if语句更改为[ "$DATE" = "$LASTSAT" ]
的提示
它删除了错误本身,但脚本将以某种方式不等于27到27(以本月为例)。
我还尝试了另一种方法来查找上一个星期六LASTSAT=$(cal|awk '{if(NF==7){SAT=$7}};END{print SAT}')
,但如果我使用-eq并且使用“with =
我非常困惑并且没有想法,我搜索了互联网并复制了其他人正在使用的确切行,但这一切都结束了。
我做错了什么?
答案 0 :(得分:2)
在测试期间,我更改了目标日期和一些变量名称,但以下脚本适用于该月的倒数第二个星期日。相对于您的脚本,关键更改是将-h
切换添加到ncal
,以关闭当天的突出显示。当awk
打印字段时,突出显示的字符显然会出现,但在执行echo
时则不可见。请注意,您可以通过grep
匹配在ncal
之后删除awk
。
#!/bin/bash
DoDay=$(ncal -h |awk '/Su/ {print $(NF-1)}')
Datum=$(date +%d)
echo $Datum Datum
echo $DoDay DoDay
if [[ $Datum == $DoDay ]]
then
echo "sista lördagen..."
else
echo "doh"
fi
答案 1 :(得分:2)
以下是使用date
打印每月最后一个星期六的一种方式:
for i in {1..12}; do
for j in {1..7}; do
date=$(date -d "$i/1 + 1 month - $j day" +"%w %F")
# day of week (1..7); 1 is Monday
if [ ${date:0:1} -eq 6 ]; then
echo ${date:2}
fi
done
done
结果:
2012-01-28
2012-02-25
2012-03-31
2012-04-28
2012-05-26
2012-06-30
2012-07-28
2012-08-25
2012-09-29
2012-10-27
2012-11-24
2012-12-29
如果您只想查找当月的最后一个星期六,请尝试:
for j in {1..7}; do
month=$(date +"%m")
date=$(date -d "$month/1 + 1 month - $j day" +"%w %F")
# day of week (1..7); 1 is Monday
if [ ${date:0:1} -eq 6 ]; then
echo ${date:2}
fi
done
结果:
2012-10-27
请注意,您只需将%F
更改为date
提供的任何格式,即可在上述脚本中更改这些结果的输出格式。请参阅man date
。
答案 2 :(得分:2)
您可以使用date
命令轻松获取当月的最后一个星期六,该命令以strftime()
格式吐出数据。但date
的语法取决于您的操作系统。
在FreeBSD或OSX 中,有一个-v
选项可以“调整”日期,让您获得很多控制权:
[ghoti@pc ~]$ date -v+1m -v1d -v6w '+%a %d %b %Y'
Sat 03 Nov 2012
[ghoti@pc ~]$ date -v+1m -v1d -v6w -v-1w '+%a %d %b %Y'
Sat 27 Oct 2012
这里的想法是我们将向前移动1个月(+1m
),然后回到本月的第一天(1d
),然后移动到本周的第6天,即星期六(6w
)。出于演示目的,第一行显示下个月的第一个星期六,第二行显示日期一周(-v-1w
)。
或者,如果你想在你的bash脚本中加入一些数学,你可以这样做:
#!/usr/local/bin/bash
# Get day-of-the-week for the first-of-the-month:
firstofmonth=$(date -j -v+1m -v1d '+%u')
# ^
# + This is the relative month to current.
# Subtract this from 7 to find the date of the month
firstsaturday=$((7 - $firstofmonth))
# 7 days before that will be the last Saturday of the previous month
lastsaturday=$(date -j -v+1m -v${firstsaturday}d -v-7d '+%Y-%m-%d')
使用-v
选项,1是1月,2是2月等。或者它可以是相对的,如我在此处所示,下个月为+1,上个月为-1,等等。
在Linux 中,日期使用-d
选项来解释日期的文字说明。所以:
#!/bin/bash
firstofmonth=$(date -d '+1 months' '+%Y%m01')
firstsaturday=$(date -d "$firstofmonth" '+%Y-%m')-$(( 7 - $(date -d "$firstofmonth" '+%u') ))
lastsaturday=$(date -d "$firstsaturday -7 days" '+%d')
请注意,如果您使用的是cron ,则可以简化此操作。您知道上个星期六将在本月的最后7天内进行,因此我们可以首先使用cron将事情限制为星期六,然后检查脚本中的最后一个月。这将在每个星期六运行脚本,但除了应该这样做之外什么都不做。例如,cron选项卡将是
# ↙ "0 0"=midnight
0 0 * * 0 /path/to/script.sh
# ↖ 0=Sunday
script.sh
将以:
#!/bin/bash
if [[ $(date '+%d' -lt $(date -d "$(date -d '+1 month' '+%Y%m01') -7 days" '+%d') ]]; then
exit
fi
你也可以把这个测试放在crontab中,虽然它看起来有点丑陋,因为你需要逃避百分号:
0 0 * * 0 \
test $(date '+\%d') -ge $(date -d "$(date -d '+1 month' '+\%Y\%m01') -7 days" '+\%d') \
&& /path/to/command
答案 3 :(得分:1)
这个怎么样:
last_saturday ()
{
local Format;
if [[ $1 =~ ^\+.* ]]; then
Format=$1;
shift;
fi;
local FirstOfNext="${1:-$(date +%B)} 1 $2 + 1 month";
date $Format -d "$FirstOfNext - 1 day -
$(($(date +%u -d "$FirstOfNext") % 7)) day"
}
例如:
$ last_saturday
Sat Oct 27 00:00:00 PET 2012
$ last_saturday November
Sat Nov 24 00:00:00 PET 2012
$ last_saturday June
Sat Jun 23 00:00:00 PET 2012
$ last_saturday June 2013
Sat Jun 29 00:00:00 PET 2013
$ last_saturday +%Y-%m-%d June 2013
2013-06-29
答案 4 :(得分:0)
该脚本在我的系统上运行正常(Ubuntu - Bash $)。
我刚刚修改了脚本以打印“!sistalördagen...”如果那天不是最后一个星期六,这是输出:
$ sh abc.sh
7
21
27
!sista lordagen ......
答案 5 :(得分:0)
#!/bin/bash
set -e
if [ "$#" -ne 2 ]; then
echo "Usage: weekDayOfMonth.sh [weekOfMonth 1..4] [DayOfWeek where Sun=1]"
exit 2;
fi
weekOfMonth=$1
dayOfWeek=$2 #starts with Sun(=1)
echo "weekOfMonth: $weekOfMonth";
echo "dayOfWeek: $dayOfWeek";
# cal starts with Sun, 3rd column is for Tue, 2nd row is 2nd Tue of month:
# Sun=1, dayIdx=0
# Mon=2, dayIdx=3
# Tue=3, dayIdx=6
# Wed=4, dayIdx=9
dayIdx=$(((dayOfWeek-1)*3))
expectedDayOfMonth=$(cal -s | sed "s/^.\{$dayIdx\}\(.\{3\}\).*$/\1/" | sed 's/^[ ]//g' | grep -o '[0-9]*' | head -$weekOfMonth | tail -1)
todaysDay=$(date +%d | sed 's/^0*//')
echo "expectedDayOfMonth: $expectedDayOfMonth";
echo "todaysDay: $todaysDay";
if [ ${expectedDayOfMonth} -ne ${todaysDay} ]; then
echo "Today is NOT requested day of month, exiting with error code.";
exit 1;
fi
答案 6 :(得分:0)
解决办法
if [[ $(date +"%a") = "Sat" ]] && [[$(date -d "+7 days" +%m) != $(date +%m)]]
then
echo "Last saturday of month"
fi
答案 7 :(得分:-1)
这个怎么样?
if [ `date +%u` = 7 ] && [ `date +%m` != `date -d +week +%m` ]; then
echo "sista lördagen..."
fi
...或仅通过crontab:
0 0 * * 0 [ `date +\%m` != `date -d +week +\%m` ] && /path/to/backup.sh