You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell/ksh脚本特定日期查询功能故障求助

Shell日期查询脚本问题排查与修复

需求概述

需要实现两种日期查询功能:

  1. 接收星期几(支持缩写/完整名,如Mon/Monday)和天数,输出过去该天数范围内所有对应星期几的日期;
  2. 接收星期范围(如Mon-Wed)和周数,输出过去该周数范围内,每周对应星期区间内的每一天日期。

原脚本代码

#!/bin/bash

read -p "Enter 1 to enter a weekday and number of past days or 2 to enter a weekday range and number of weeks: " option

case "$option" in
  1)
    read -p "Enter a weekday (Monday, Tuesday, etc.): " day
    read -p "Enter number of past days: " days
    start_time="00:00:00"
    end_time="24:00:00"
    for (( i=0; i<=$days; i++ )); do
      date=$(date --date="$i days ago" +%Y%m%d)
      day_of_week=$(date --date="$i days ago" +%A)
      if [ "$day_of_week" == "$day" ]; then
        echo "Date: $date $start_time, End time: $date $end_time"
      fi
    done
    ;;
  2)
    read -p "Enter a weekday range (e.g. Mon to Wed): " range
    read -p "Enter number of weeks: " weeks
    start_time="00:00:00"
    end_time="24:00:00"
    range_array=($(echo $range | tr '-' ' '))
    start_weekday=${range_array[0]}
    end_weekday=${range_array[-1]}
    for (( i=0; i<=$((weeks*7)); i++ )); do
      date=$(date --date="$i days ago" +%Y%m%d)
      day_of_week=$(date --date="$i days ago" +%A)
      if [ "$day_of_week" == "$start_weekday" ]; then
        start_date=$date
      elif [ "$day_of_week" == "$end_weekday" ]; then
        end_date=$date
        echo "Start date: $start_date $start_time, End date: $end_date $end_time"
       
      fi
    done
    ;;
  *)
    echo "Invalid input"
    exit 1
    ;;
esac

问题排查

功能1的问题

  1. 星期格式不兼容:脚本用%A获取完整星期名(如Monday),但用户可能输入缩写(如Mon),导致匹配失败;
  2. 重复调用date命令:每次循环两次调用date,冗余且效率低;
  3. 循环范围歧义:i<=days会包含今天(i=0),不符合“过去N天”的常规理解(通常不含当天)。

功能2的问题

  1. 输入处理逻辑混乱:提示示例是Mon to Wed,但脚本用tr '-' ' '处理减号,用户输入Mon to Wed会被分割为Mon、to、Wed,导致end_weekday取值错误;
  2. 星期格式不兼容:同样存在完整名与缩写不匹配的问题;
  3. 核心逻辑错误:当前脚本仅记录区间首尾日期并输出组合,未实现“输出范围内每一天的日期”的需求;
  4. 循环范围逻辑错误:weeks*7的循环范围未考虑星期区间的跨周问题,且未按需求遍历输出对应区间的每一天。

修复后的脚本

#!/bin/bash

# 统一星期转换函数:将输入的星期(缩写/完整名)转为数字(1=周一,7=周日)
get_weekday_num() {
  local input_day=$1
  # 处理完整名和缩写,忽略大小写
  case "${input_day,,}" in
    mon|monday) echo 1 ;;
    tue|tuesday) echo 2 ;;
    wed|wednesday) echo 3 ;;
    thu|thursday) echo 4 ;;
    fri|friday) echo 5 ;;
    sat|saturday) echo 6 ;;
    sun|sunday) echo 7 ;;
    *) echo "Invalid weekday" >&2; exit 1 ;;
  esac
}

read -p "输入1查询指定星期的历史日期,输入2查询星期区间的历史日期:" option

case "$option" in
  1)
    read -p "输入星期几(支持缩写/完整名,如Mon/Monday):" day
    read -p "输入查询的过去天数:" days
    start_time="00:00:00"
    end_time="24:00:00"
    target_num=$(get_weekday_num "$day")

    # 从1开始循环,排除今天,查询过去days天内的日期
    for (( i=1; i<=$days; i++ )); do
      # 一次获取日期和星期数字,减少冗余调用
      read -r date_str weekday_num <<< $(date --date="$i days ago" +"%Y%m%d %u")
      if [ "$weekday_num" -eq "$target_num" ]; then
        echo "日期: $date_str $start_time, 结束时间: $date_str $end_time"
      fi
    done
    ;;
  2)
    read -p "输入星期范围(格式如Mon-Wed):" range
    read -p "输入查询的过去周数:" weeks
    start_time="00:00:00"
    end_time="24:00:00"

    # 用减号分割星期范围,正确解析首尾星期
    IFS='-' read -r start_day end_day <<< "$range"
    start_num=$(get_weekday_num "$start_day")
    end_num=$(get_weekday_num "$end_day")

    # 计算总查询天数:过去weeks周,即weeks*7天前到昨天
    total_days=$((weeks * 7))
    for (( i=1; i<=$total_days; i++ )); do
      read -r date_str weekday_num <<< $(date --date="$i days ago" +"%Y%m%d %u")
      # 判断当前星期是否在区间内,支持跨周日的情况(如Fri-Sun)
      if [ "$start_num" -le "$end_num" ]; then
        if [ "$weekday_num" -ge "$start_num" ] && [ "$weekday_num" -le "$end_num" ]; then
          echo "日期: $date_str $start_time, 结束时间: $date_str $end_time"
        fi
      else
        if [ "$weekday_num" -ge "$start_num" ] || [ "$weekday_num" -le "$end_num" ]; then
          echo "日期: $date_str $start_time, 结束时间: $date_str $end_time"
        fi
      fi
    done
    ;;
  *)
    echo "无效输入"
    exit 1
    ;;
esac

修复说明

  1. 新增星期转换函数:支持缩写和完整名输入,统一转为星期数字(1-7),彻底解决格式匹配问题;
  2. 优化date调用:一次获取日期和星期数字,减少冗余系统调用;
  3. 功能1逻辑调整:循环从1开始,排除今天,符合“过去N天”的常规理解;
  4. 功能2输入处理:用IFS='-'正确分割Mon-Wed格式的范围,修复输入解析错误;
  5. 功能2核心逻辑修复:支持跨周日的星期区间判断,输出区间内每一天的日期,完全符合需求;
  6. 交互优化:调整为中文提示,更贴合国内使用习惯。

内容的提问来源于stack exchange,提问作者abhishek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:40:25