3

毎月最後の土曜日を見つける必要があるバックアップ スクリプトを作成しています。

私は日自体を見つけるためにさまざまなアプローチを試みましたが、それはそれ自体が見事に機能します。

問題は、それらをスクリプトに入れようとすると、常にエラー コードが表示されることです ./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 = を使用して 27 から 27 に等しくない場合、まったく同じエラーが返されます。

私は非常に混乱していてアイデアがありません。インターネットを検索し、他の人が使用していた正確な行をコピーしましたが、すべて同じ結果になります.

私は何を間違っていますか?

4

8 に答える 8

3

データを形式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) というものです。デモンストレーションのために、最初の行は翌月の最初の土曜日を示し、2 行目は1 週間前( -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 では、 date は、日付-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
于 2012-10-22T11:20:36.660 に答える
3

テスト中に、対象日といくつかの変数名を変更しましたが、次のスクリプトは、その月の最後から 2 番目の日曜日に対して機能します。スクリプトに関連する重要な変更は、-hスイッチをに追加してncal、現在の日の強調表示をオフにすることでした。強調表示された文字awkは、フィールドを印刷すると明らかに表示されますが、s を実行すると表示されませんecho。試合を介してgrepアフターをドロップできることに注意してください。ncalawk

#!/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
于 2012-10-22T00:38:54.047 に答える
2

を使用して各月の最後の土曜日を出力する 1 つの方法を次に示します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

于 2012-10-22T00:58:38.350 に答える
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
于 2012-10-22T03:30:32.117 に答える
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
于 2015-05-21T14:00:33.953 に答える
0

スクリプトは私のシステム (Ubuntu - Bash $) で正常に動作します。その日が最後の土曜日ではなく、これが出力である場合、「!sista lördagen ...」を出力するようにスクリプトを変更しました:
$sh abc.sh
7
21
27
!sista Lordagen ...

于 2012-10-22T00:09:50.383 に答える