我希望你们中的一个人,bash,awk专家可以帮助我。我有这个字符串:
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
由“%〜%”分隔的字段。前两个字段可以忽略。其余字段具有日期时间范围。这应该澄清格式:
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
现在的诀窍......我需要确定当前系统日期时间是否在范围内。 : - (
所以,如果日期返回:
Wed Sep 19 14:26:05 UTC 2012
然后它不在星期三指定的范围内。我基本上需要一个if语句。如果它在范围内,我需要执行一个脚本,如果不是,则需要执行不同的脚本。我怎么能用bash,awk和/或sed做到这一点?
感谢您提供的任何帮助!
我开始走这条路:
arr=$(echo $line | tr "%~% " "\n")
for x in $arr
do
#Now what? Some kind of switch/case?
done
答案 0 :(得分:1)
我相信以下脚本可以满足您的需求:
#!/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 :(得分:1)
这是使用awk的解决方案。我认为getline / coprocess特性是特定于GNU Awk的,所以如果你发现这个解决方案可以接受,请确保使用它。
<强> script.awk 强>
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")
}
}
<强>用法强>
$ 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
我希望我能正确理解你的问题。随意请求澄清。
答案 2 :(得分:1)
使用GNU awk
的一种方式:
echo "$string" | awk -f script.awk
script.awk
的内容:
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"
}
}
}
}