首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用bash解析日期时间范围

使用bash解析日期时间范围
EN

Stack Overflow用户
提问于 2012-09-20 05:35:18
回答 3查看 1.1K关注 0票数 0

我希望你们中的一位bash,sed,awk专家能帮到我。我有这个字符串:

代码语言:javascript
运行
复制
 00:00:00:00:00:00%~%System1%~%s0:00-21:40%~%m3:10-17:10%~%t11:20-20:30%~%w05:10-9:30%~%t00:00-21:30%~%f12:00-0:00%~%s6:00-18:00     

它是由"%~%“分隔的字段。前两个字段可以忽略。其余字段具有日期时间范围。这应该会澄清格式:

代码语言:javascript
运行
复制
00:00:00:00:00:00 <--Mac
System1           <--Name
s00:00-21:40      <--Sunday 12 AM through 9:40 PM  
m03:10-17:10      <--Monday 3:10 AM through 5:10 PM
t11:20-20:30      <--Tuesday 11:20 AM through 8:30 PM
w05:10-9:30       <--Wednesday 5:10 AM through 9:30 AM
t00:00-21:30      <--Thursday 12 AM through 9:30 PM
f12:00-0:00       <--Friday 12 PM through 12:00 AM
s06:00-18:00      <--Saturday 6 AM through 6:00 PM

现在的诀窍是...我需要确定当前系统日期时间是否在范围内。:-(

因此,如果date返回以下内容:

代码语言:javascript
运行
复制
 Wed Sep 19 14:26:05 UTC 2012

那么它就不会落在星期三指定的范围内。我基本上需要一个if语句。如果在范围内,我需要执行一个脚本,如果不在范围内,则需要执行一个不同的脚本。我该如何使用bash、awk和/或sed来做到这一点?

感谢您能提供的任何帮助!

我开始走这条路:

代码语言:javascript
运行
复制
arr=$(echo $line | tr "%~% " "\n")
for x in $arr
do
    #Now what?  Some kind of switch/case?
done
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-20 06:37:07

我相信下面的脚本可以满足您的需求:

代码语言:javascript
运行
复制
#!/bin/bash

# Function which returns true (0) on a time being in a range, false (1) otherwise
# call as: time_between $time $range
# where $range is of the format 'START-END'
time_between() {
    current_time=$1
    range=$2

    start_time=$(echo $range | cut -d'-' -f1);
    end_time=$(echo $range | cut -d'-' -f2);

    # Correct if ends at midnight
    if [[ $end_time -eq 0 ]]; then
        let end_time=2400
    fi

    # Test is time is within the window
    if [[ $current_time -ge $start_time && $current_time -le $end_time ]]
    then
         return 0;
    fi

    # Else the time is outside the window
    return 1;
}

# Set the line variable - you may want this to come from somewhere else in the end  
line="00:00:00:00:00:00%~%System1%~%s0:00-21:40%~%m3:10-17:10%~%t11:20-20:30%~%w05:10-9:30%~%t00:00-21:30%~%f12:00-0:00%~%s6:00-18:00"

i=0

# Extract the day and time (hours and minutes) from the `date` command
DATE=$(date)
day=$(echo $DATE | cut -d' ' -f1)

time=$(echo $DATE | cut -d' ' -f4 | cut -d: -f1-2 | tr -d ':')

# Marker for which token in the line to start the days from: token 3 is monday
dayno=2

# Set the dayno so we're pointing at the current day
case $day in
Mon)
    let dayno+=1
;;
Tue)
    let dayno+=2
;;
Wed)
    let dayno+=3
;;
Thu)
    let dayno+=4
;;
Fri)
    let dayno+=5
;;
Sat)
    let dayno+=6
;;
Sun)
    let dayno+=7
;;
esac

arr=$(echo $line | tr '%~%' '\n' | tr -d '[a-z]:')

for x in $arr
do
    let i+=1;
    #Now what?  Some kind of switch/case?
    if [[ $i -eq $dayno ]]; then
        if time_between $time $x; then
            echo "Were within the window!"
        else
            echo "We missed the window!"
        fi
    fi
done
票数 1
EN

Stack Overflow用户

发布于 2012-09-20 06:46:38

这是一个使用awk的解决方案。我认为getline/coprocess特性是特定于GNU Awk的,所以如果你觉得这个解决方案是可以接受的,那么一定要使用它。

script.awk

代码语言:javascript
运行
复制
BEGIN {
    RS = "%~%"
    "date +%w"   | getline dow
    "date +%H%M" | getline now
}

NR == 1      { mac = $0; next }
NR == 2      { sys = $0; next }

NR == 3+dow  {
    str = $0
    gsub(/[smtwf:]/, "", str)
    split(str, period, "-")
    next
 }

END {
    print "MAC:",  mac;
    print "System:", sys;
    print "Now:", now;
    print "Period:", period[1], period[2] ;

    if ((now >= period[1]) && (now <= period[2])) {
         # change this ...
         cmd = sprintf("echo matched - mac: %s system: %s", mac, sys)
         system(cmd)
    } else {
         # ... and this
         system("echo not matched")
    }
}

使用

代码语言:javascript
运行
复制
$ date
Thu Sep 20 01:44:12 EEST 2012

$ echo "$data" | awk -f script.awk 
MAC: 00:00:00:00:00:00
System: System1
Now: 0145
Period: 0000 2130
matched - mac: 00:00:00:00:00:00 system: System1

我希望我已经正确地理解了你的问题。请随时要求澄清。

票数 1
EN

Stack Overflow用户

发布于 2012-09-20 08:34:17

使用GNU awk的一种方式

代码语言:javascript
运行
复制
echo "$string" | awk -f script.awk

script.awk的内容

代码语言:javascript
运行
复制
BEGIN {
    FS="%~%"
    day = strftime("%w") + 3
    time = strftime("%H%M")
}

{
    for (i=1; i<=NF; i++) {
        if (i == day) {
            gsub(/[a-z:]/,"")
            split($i, period, "-")
            if ((time >= period[1]) && (time <= period[2])) {
                print "yes, we're within today's range"
            }
            else {
                print "no, we're not within today's range"
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12503251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档