#!/ bin / bash内。月の平日の最初の日付を取得するUnixコマンド


8

来月の最初の日曜日、来月の最初の月曜日、来月の最初の火曜日、来月の最初の水曜日などを取得するストレートなUnixコマンドを探しています。

  1. 私は完全な日付形式でそれらを必要とします(時間は必須ではありません)

  2. 2、3、4などの数値を取得できます。数値だけが必要ではないため、日付形式(日、月、年を含む)で必要になります。

    $ NEXT_MONTH=`date +'%m %Y' -d 'next month'`
    $ echo $NEXT_MONTH
    04 2017
    
    $ NEXT_SUNDAY=`cal $NEXT_MONTH | awk 'NF==7 && !/^Su/{print $1;exit}'`
    $ echo $NEXT_SUNDAY
    2
  3. メールグループの通知を送信するには、これらの日付が必要です。

例:来月の第1土曜日は以下のようになります。

$ firstofmonth=$(date -d '+1 months' '+%Y%m01')
20170401

$ firstsaturday=$(date -d "$firstofmonth" '+%Y-%m')-$((7 - \
                $(date -d "$firstofmonth" '+%u')     ))    
2017-04-1

回答:


11

ksh93

$ printf '%(%F)T\n' 'next month, first Monday'
2017-04-03

bash、4.2は現在%(<format)Tそのprintfbuitinでa をサポートしていますが、この種の日付式を解析する機能はサポートしていません。

を使用する必要があり、それを使用bashしたい%(<format>)T場合でも、次のようなものをフォークせずに実行できます。

printf -v code '%(
  t=$((%s + (12 - %-H) * 60 * 60))
  increment=$((8 - %u))
  current_month=%m)T' -1
eval "$code"
until
  t=$((t + increment * 24 * 60 * 60)) # next Monday around mid-day
  printf -v code '%(date=%F month=%m)T' "$t"
  eval "$code"
  [ "$month" != "$current_month" ] # until be get to next month
do
  increment=7 # the first increment is the number of days
              # til Monday. Next increments are just a week.
done
echo "$date"

#!/ bin / bash。bash $ printf '%(%F)T \ n' 'next month、first Monday' -bash:printf: `( ':無効なフォーマット文字
Hima

1
@ヒマ、私はksh93で言っbashkshの未完成のクローンです((t)cshとzshのいくつかの機能と、それ自体のいくつかの機能を備えています)。の最近のバージョンでbashは、printf '%(format)T'fromのサポートが追加されていますがksh93、この種の日付指定を解析する機能はありません。シーバンをに置き換えます#! /path/to/ksh93 -
ステファンChazelas

bashkshの未完成のクローンです」-私はいつもそのように感じていました。
ティムケネディ

@Stephene、私は次のコマンドを使って来月の最終土曜日$ cal 04 2017を取得しようとしました| awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | tail -1 28数値28が表示されますが、完全な日付を探しています。
ヒマ

9

GNUと仮定すると、date(そのために-d自分自身を使用している)、およびzsh様シェルのために{1..7}

$ for i in {1..7} ; do \
    LC_ALL=C date '+%Y-%m-%d %a' -d "$(date +%Y%m0${i}) next month" ; \
  done | awk '/Mon/ {print $1}'
2017-04-03

awk Mon必要な曜日に置き換えます(LC_ALL=Cユーザーのロケールに関係なく英語の月名を取得するために使用します)。また、曜日ごとに再クエリを実行する場合は、これを変数に格納することをお勧めします。

$ days=$(for i in {1..7} ; do \
           LC_ALL=C date '+%Y-%m-%d %a' -d "$(date +%Y%m0${i}) next month" ; \
         done)

$ for i in Mon Tue Wed Thu Fri Sat Sun ; do \
    echo "${days}" | awk "/${i}/"'{print $1}' ; \
  done
2017-04-03
2017-04-04
2017-04-05
2017-04-06
2017-04-07
2017-04-01
2017-04-02

bashでも、このコードは翌月を最初の日、月、水、したがって、金、土を返します。ありがとうございました。私はこのコマンドを変更して、先月の日曜、月曜、水曜などを取得できると思います。これを試してみましょう。
ヒマ

こんにちは、私は次のコマンドを使って、先月の土曜日$ cal 04 2017を取得しました。awk 'NF <= 7 {print $ 6}' | grep -v "^ $" | tail -1 28を表示しますが、2017年4月28日のような完全な日付を探しています。可能であれば、plzが提案します。
ヒマ

"for i in {1..7}; do date '+%Y-%m-%d%a' -d" $(date +%Y%m01 -d '2 months')$ {i}日前";完了| awk '/ Sat / {print $ 1}'"-これにより、翌月の最後の土曜日である2017-04-29が得られます。このコードは2か月先のその月の最初の日まで進み、次に1〜7日戻って前月の最後の7日間のデータを取得します。ここで他の例を試したので、個人的にはcalの使用を避け、私のバージョン(CentOS 6)ではまったく機能しません。
parkamark 2017年

2

PHPは、システムで使用できる場合、テキスト入力で日付を解析することをかなり簡単にします。

例:

bash-[522]$ php -qr 'date_default_timezone_set("UTC"); echo date("d-m-Y\n", strtotime("first monday of next month"));'
03-04-2017

私の.bashrcにこの関数があります:

get_date ()
{
    text="$*";
    php -qr "date_default_timezone_set(\"UTC\"); echo date(\"d-m-Y\n\", strtotime(\"$text\"));"
}

私は次のように使用できます:

bash-[523]$ get_date first monday of next month
03-04-2017

使用する追加オプションの編集cal

持っているほとんどすべてのシステムが持ってbashcalます。カレンダープログラム。あなたは、の組み合わせを実行することにより、各曜日の最初の日付のリストを取得することができcaldateおよびawk以下のように、:

 cal -hN $(date -d 'next month' +%b' '%Y) | grep -v $(date -d 'next month' +%b) | awk -v date=$(date -d 'next month' +%Y-%m-) '{ printf "%s: "date"%02i\n", $1, $2; }'

これにより、次の出力が得られます。

Su: 2017-04-02
Mo: 2017-04-03
Tu: 2017-04-04
We: 2017-04-05
Th: 2017-04-06
Fr: 2017-04-07
Sa: 2017-04-01

awkステートメントのに変更$2$NFて、月の各日の最後の発生の日付を取得します。


$ php -qr 'date_default_timezone_set( "UTC"); bashでは機能しません。echo date( "dmY \ n"、strtotime( "来月の最初の月曜日")); ' -bash:php:コマンドが見つかりません。bashでそれを実行する方法も教えてください。また、来月の土曜から土曜までを取得するコマンド。私はそれを試しました、いくつかはそれがエラーを投げる方法です。ありがとう.. !!
ヒマ

phpインストールしていないという意味です。私が使用した例で更新しているcaldateawkのコマンドを。
ティムケネディ

このコマンドを試したところ、エラーが発生しました。ありがとうございました。!!$ cal -hN $(date -d '翌月' +%b ''%Y)| grep -v $(date -d '翌月' +%b)| awk -v date = $(date -d 'next month' +%Y-%m-) '{printf "%s:" date "%02i \ n"、$ 1、$ 2; } 'cal:無効なオプション-h使用法:cal [-13smjyV] [[month] year]
Hima
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.