shellは2つの日付範囲のすべての日付を巡回出力する方法です。


前言
通常のc/c++開発において、日付処理が頻繁に行われる場合、例えば、与えられた2つの日付の間の差の日数を求めたり、mapを使って2つの固定日付範囲内のすべての日付を保存する必要があります。先日のプロジェクトの中でshellスクリプトで与えられた二つの日付範囲内のすべての日付によって発生したログを一括処理する必要がありました。その時、shellは処理が不便だと思って、c++で処理しました。後はshellで実現しましたが、簡単です。

一、考え方の流れ
      1、この2つの日付を直接整数として減算して差を得ることができないことは明らかです。そして、初期日付を絶えず累積して、すべての日付を取得して、しかも大きさの月の問題を考慮しなければなりません。
      2、今後の開発の利便性のために、この二つの固定された前期範囲のすべての日付機能を一つの関数(つまり次のシナリオの中のgenAlldate)にパッケージする必要があります。
しかし、shellのfunctionはC/C++のように一つのデータタイプをリセットできないし、引用やポインタの機能もないので、まず配列変数DATE(u)を宣言する必要があります。ARRAYは、計算されたすべての日付を保存し、関数遍歴中に直接日付データを書き込みます。
      3、最後に3つの方法を使って、出力配列DATE_を巡回しました。ARRAYに預けられたすべての日付。
      4、出力の日付フォーマットはできるだけカスタマイズできます。例えば、2017-03-30、2017.06.18、2017618などです。
二、shellプログラム

#!/bin/bash
# FileName: alldateduringtwodays1.sh
# Description: Print all the date during the two days you inpute.
# Simple Usage: ./alldateduringtwodays1.sh 2017-04-01 2017-06-14 or ./alldateduringtwodays1.sh 20170401 20170614 [-]
# (c) 2017.6.15 vfhky https://typecodes.com/linux/alldateduringtwodays1.html
# https://github.com/vfhky/shell-tools/blob/master/datehandle/alldateduringtwodays1.sh


if [[ $# -le 2 || $# -gt 3 ]]; then
 echo "Usage: $0 2017-04-01 2017-06-14 [-] or $0 20170401 20170614 [-] ."
 exit 1
fi

START_DAY=$(date -d "$1" +%s)
END_DAY=$(date -d "$2" +%s)
# The spliter bettwen year, month and day.
SPLITER=${3}


# Declare an array to store all the date during the two days you inpute.
declare -a DATE_ARRAY


function genAlldate
{
 if [[ $# -ne 3 ]]; then
 echo "Usage: genAlldate 2017-04-01 2017-06-14 [-] or genAlldate 20170401 20170614 [-] ."
 exit 1
 fi

 START_DAY_TMP=${1}
 END_DAY_TMP=${2}
 SPLITER_TMP=${3}
 I_DATE_ARRAY_INDX=0

 # while [[ "${START_DAY}" -le "${END_DAY}" ]]; do
 while (( "${START_DAY_TMP}" <= "${END_DAY_TMP}" )); do
 cur_day=$(date -d @${START_DAY_TMP} +"%Y${SPLITER_TMP}%m${SPLITER_TMP}%d")
 DATE_ARRAY[${I_DATE_ARRAY_INDX}]=${cur_day}

 # We should use START_DAY_TMP other ${START_DAY_TMP} here.
 START_DAY_TMP=$((${START_DAY_TMP}+86400))
 ((I_DATE_ARRAY_INDX++))

 #sleep 1
 done
}

# Call the funciotn to generate date during the two days you inpute.
genAlldate "${START_DAY}" "${END_DAY}" "${SPLITER}"


# [Method 1] Traverse the array.
echo -e "[Method 1] Traverse the array."
for SINGLE_DAY in ${DATE_ARRAY[@]};
do
 echo ${SINGLE_DAY}
done


# [Method 2] Traverse the array.
echo -e "
[Method 2] Traverse the array." for i in "${!DATE_ARRAY[@]}"; do printf "%s\t%s
" "$i" "${DATE_ARRAY[$i]}" done # [Method 3] Traverse the array. echo -e "
[Method 3] Traverse the array." i=0 while [ $i -lt ${#DATE_ARRAY[@]} ] do echo ${DATE_ARRAY[$i]} let i++ done # If you do not need this array any more, you can unset it. # unset DATE_ARRAY exit 0
三、テスト
このshellスクリプトがサポートする入力日付フォーマットは2017-04-01と2017401の2種類で、出力の日付フォーマットは柔軟であり、プログラムを実行する時に、任意の日付区切り子(例えば、一般的な.、-など)を追加すればよく、最後に脚本のSPLITER変数によってフォーマット制御が行われる。
ここで使用します。/alldateduringtwodays 1.sh 2010-03-30 2017-04-02.テストを行います。効果は下図のようになります。

四、スクリプト管理
現在はすでにこの脚本をGithubに置いています。住所はhttps://github.com/vfhky/shell-toolsです。(ローカルダウンロードを通じてもいいです。)今後は脚本の更新や、より多くの使いやすい脚本もこのプロジェクトに参加します。
締め括りをつける
以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に一定の助けをもたらすことを望んでいます。もし疑問があれば、メッセージを残して交流してください。ありがとうございます。