shell遍历输出两个日期范围内所有的日期

2017-06-19 15:32:50

在平常c/c++开发中经常遇到日期处理的情形,例如求两个给定的日期之间相差的天数或者需要使用map存储两个固定日期范围内的所有日期。前段时间项目中需要用shell脚本批量处理给定的两个日期范围内所有日期产生的日志,当时以为shell处理不方便就用c++来处理了。后面用shell实现了下,发现也挺简单的。

1 思路流程

1、显然不能直接把这两个日期当作整数相减得到差值然后把初始日期不断累加1得到所有的日期,而且要考虑大小月的问题。

2、为了以后开发的方便,需要把这个求两个固定上期范围内的所有日期功能封装在一个函数(即下面脚本中的 genAlldate )中。

但是shell的 function 不能像C/C++那样能return一个数据类型,也没有引用或者指针的功能,所以在需要先声明一个数组变量 DATE_ARRAY 用于存放计算出来的所有日期,然后在函数遍历中直接写入每个日期数据。

3、最后使用了3种方法来遍历输出数组 DATE_ARRAY 存放的所有日期。

4、输出的日期格式尽量能够自定义,例如2017-03-30、2017.06.18和20170618等等(由小节2中的 SPLITER 变量实现)。

2 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 "\n[Method 2] Traverse the array."
for i in "${!DATE_ARRAY[@]}"; do 
    printf "%s\t%s\n" "$i" "${DATE_ARRAY[$i]}"
done


# [Method 3] Traverse the array.
echo -e "\n[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

3 测试

该shell脚本支持的输入日期格式为 2017-04-0120170401 这两种,输出的日期格式格式很灵活,只要在执行程序时再追加一个任意日期分隔符(例如常见的 .- 等)即可。

这里使用 ./alldateduringtwodays1.sh 2017-03-30 2017-04-02 . 进行测试,效果如下图所示。

4 脚本管理

目前已经把这个脚本放在Github了,地址是 https://github.com/vfhky/shell-tools ,以后脚本的更新或者更多好用的脚本也都会加入到这个工程中。

同时,BZ也把修改后的Makefile文件同步更新到了对应的Github上了,欢迎关注,地址还是之前的: https://github.com/vfhky/General_Makefile

相关帖子
用户评论
开源开发学习小组列表