2016-04-30 12 views
1

PowerShellの-match演算子と\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})正規表現を使用して、再起動が発生するはずの日と時刻を取得します。24時間で先行ゼロを追加する書式設定文字列

サンプルデータ:

Patching - Prod - Fri 2:00 
Patching - Prod - Fri 22:00 
Patching - Prod - Thu 22:00 
Patching - Prod - Fri 22:00 
Patching - Prod - Sat 18:00 
Patching - Prod - Sun 2:00 
Patching - Prod - Sun 00:00 
Patching - Prod - Sat 2:00 

$Rebootinfo = "Patching - Prod - Sat 2:00" 

"$Rebootinfo" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})" | Out-Null 

これは素晴らしい作品が、私は時間が2:00 AMあるとき、私は2:00を取得し、時間があれば私も02:00のための先行ゼロとなるパッドに探しています見つけました真夜中、結果は0の代わりに希望の00:00

私はthis articleからの提案を試してきました。

"Prod - Sun 2:00" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})" | Out-Null 

$a = $Matches[2] 
$a.ToString("00:00") 

エラーを返します。 "ToString"と引数count: "1"のオーバーロードが見つかりません。

私の目標は、PowerShellにデータを渡して、その再起動までの日数を取得することです。例として、土曜日に実行する場合、日曜日の午前2時は1日追加する必要があります。

答えて

1

あなたはこれを行うことができます:

 
"Prod - Sun 2:00" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9][:]\d{2})" | Out-Null 
$a = $Matches[2] 
$ts = [TimeSpan]::Parse($a) 
$formatted = $ts.ToString("c").Substring(0, 5) 
$formatted 

それは$formattedため02:00を出力します。

+0

私はこれを、別のコードスニペットと共に使用して終了しました。 – user4317867

0

あなたの投稿に質問はありません(目標はありますが質問はありません)。だから私はあなたの質問は "なぜ正規表現は'02:00AM 'を返さないと思いますか?

2の前にソース文字列に0が含まれていないため、ソース文字列にゼロが含まれている一致を得ることができません。別のステップとして追加する必要があります。

.NETの組み込み日付時刻解析:[datetime]::parseexactを使用すると、何らかの問題を回避できます。残念ながら、ParseExactはSunが現在の日でない場合は "Sun 2:00 AM"のような文字列を処理できないため、余分な作業が必要です。ここにいくつかの同じサンプルコードがあります。

$Rebootinfo = "Patching - Prod - Thu 2:00AM" 

$splitUp = $Rebootinfo -split "\b(Thu|Fri|Sat|Sun)" 
# $splitUp[-1] now contains time and $splitUp[-2] contains day of week 

$cult = [Globalization.CultureInfo]::InvariantCulture 
try { 
    $rebootTime = [datetime]::parseexact($splitUp[-1], " h:mmtt", $cult) 
} catch { 
    # put your own error handling here 
    throw "Date time parse failed" 
} 

$weekDayToWeekDayNumber = @{Sun=0;Mon=1;Tue=2;Wed=3;Thu=4;Fri=5;Sat=6} 
$rebootWeekDayNumber = $weekDayToWeekDayNumber[$splitUp[-2]] 
$todayWeekDayNumber = $weekDayToWeekDayNumber[[datetime]::today.DayOfWeek.tostring().substring(0,3)] 
# This calculation fails if the reboot day of the week is same as current 
# day of week and reboot time is before current time. However I'm guessing 
# this won't be a problem because if this 
# happens you've already missed the boot or the boot is almost a week away. 
# Assuming the later: since you only have days of the week (and not dates) 
# I'm guessing that 
# boots almost a week away aren't a concern. The reason is that if you 
# handle boots almost a 
# week away, there's no guarantee (that I see) that the boot won't be a 
# little more than a week away (since you don't know exactly when the boot 
# is, hence the script). And if boots can be more than a week away you won't 
# be able to distinguish between boots this week and boots next week (since 
# you only have the day of the week). 
# However if this is a problem, just compare $rebootTime to [datetime]::now 
# and if less, then add 7 more days to $rebootTime. 
$rebootTime = $rebootTime.AddDays(($rebootWeekDayNumber - $todayWeekDayNumber + 7) % 7) 

write-host Amount of time till reboot ($rebootTime - [datetime]::now) 
3

文字列に数字書式を使用することはできないため、時間/分をintに変換する必要があります。

#Convert 2:00 to 200 int-number and format it to 00:00-style -> 02:00. 
#18:00 -> 1800 -> 18:00 
"{0:00:00}" -f ([int]$a.Replace(":","")) 

それとも

#Capture hour and minutes in their own groups 
"Prod - Sun 2:00" -match "\b(Thu|Fri|Sat|Sun).([012]?[0-9])[:](\d{2})" | Out-Null 
#Format 00 only works with digits, so convert to int 
"{0:00}:{1:00}" -f [int]$Matches[2], [int]$Matches[3] 

それとも日時にそれを解析し、正しい形式で戻って文字列に変換する(またはしたい場合のDateTimeオブジェクトを使用する)ことができます:ここではいくつかの例があります。

$date = [datetime]::ParseExact($Matches[0], "ddd H:mm", [cultureinfo]::InvariantCulture) 
$date.ToString("ddd HH:mm", [cultureinfo]::InvariantCulture) 
+2

@ user4317867あなたの質問履歴を考えれば、私は、DateTimeの値を文字列に戻さずに3番目の方法を使用することをお勧めします。これにより、実際のタイムスタンプとして次のメンテナンスウィンドウの時間が表示されます。 –

関連する問題