2008年3月3日
#
ちょっと仕事も飽きてきたので息抜きに
指定した年月のカレンダーを表示する の色つき版を作ってみました。
実行結果は下記の下段のほうです。
上段のほうは、前回の実行結果です。
以下ソース
Get-Calendar2.ps1
#===============================================================================
# Get-Calendar2: 指定した年月のカレンダーを表示する(色つき版)
#
# パラメータ:
# $Year: 年(省略した場合は現在の年)
# $Month: 月(省略した場合は現在の月)
#
# 使用例1(年月指定)
# PS > Get-Calendar2 2008 2
#
# 使用例2(年月省略)
# PS > Get-Calendar
#
# copyright HIRO's.NET(http://hiro.wankuma.com/)
#===============================================================================
function global:Get-Calendar2
{
Param ([int]$Year = $(Get-Date).Year, [int]$Month = $(Get-Date).Month)
#表示用年月作成
$DispMonth = New-Object DateTime($Year, $Month, 1)
$strDispMonth = ($DispMonth.ToString("MMMM",[System.Globalization.CultureInfo]'en-US') + " " + $Year)
#横幅35文字の中間に表示されるようにする
Write-Host ""
Write-Host $strDispMonth.PadLeft([int](35 - (35 - $strDispMonth.Length) / 2))
$firstSunday = Get-FirstSunday $Year $Month
$lastDay = Get-LastDay $Year $Month
Write-Host "Sun." -foregroundcolor Red -noNewline
Write-Host " Mon. Tue. Wed. Thu. Fri. " -noNewline
Write-Host "Sat." -foregroundcolor Cyan
# 第1日曜日が"1日"以外の第1週を表示
if ( $firstSunday -ne 1 )
{
for ( $i = 1; $i -lt $firstSunday - 1; $i++ )
{
$week += $i.ToString(" # ")
}
$spc = " "
$spc *= [int](7 - ( $firstSunday - 1 ))
Write-Host ($spc + $week) -noNewline
#土曜日をCyanにする
Write-Host ($firstSunday - 1).ToString(" # ") -foregroundcolor Cyan
}
#中間週を表示
$loopWeek = [Math]::floor(($LastDay - $firstSunday) / 7)
$Day = $firstSunday
for ( $weekCnt = 0; $weekCnt -lt $loopWeek; $weekCnt++ )
{
for ( $iDay = 0; $iDay -lt 7; $iDay++ )
{
if ( $Day -lt 10 ) { $strDay = $Day.ToString(" # ") }
else { $strDay = $Day.ToString(" ## ") }
#日曜日はRed, 土曜日はCyanにする
if ($iDay -eq 0 ) { Write-Host $strDay -foregroundcolor Red -noNewline }
elseif ($iDay -eq 6 ) { Write-Host $strDay -foregroundcolor Cyan}
else { Write-Host $strDay -noNewline }
$Day += 1
}
#Write-Host ($week)
}
#最終週を表示
if ( $Day -le $LastDay )
{
$week = ""
$LastSunday = $Day
$Day += 1
for ( $iDay = $Day; $iDay -le $LastDay - 1; $iDay++ )
{
$week += $Day.ToString(" ## ")
$Day += 1
}
#最終週の日曜日の色をRedにする
Write-Host $LastSunday.ToString(" ## ") -foregroundcolor Red -noNewline
Write-Host $week -noNewline
#最終日が土曜日の場合は色をCyanにする
if ($LastDay - $LastSunday -eq 6) { Write-Host $LastDay.ToString(" ## ") -foregroundcolor Cyan }
else { Write-Host $LastDay.ToString(" ## ") }
}
}
ポイントは
Write-Hostコマンドレットで色を付けているということです。
前景色(文字色)はパラメータ -foregroundcolor で指定することができます。
指定可能な色は
- Black
- DarkBlue
- DarkGreen
- DarkCyan
- DarkRed
- DarkMagenta
- DarkYellow
- Gray
- DarkGray
- Blue
- Green
- Cyan
- Red
- Magenta
- Yellow
- White
です。
あとは むたぐちさんに Write-Hostコマンドレットは、-noNewlineパラメータを使用すれば改行しないで文字を出力できることを教えていただきましたので、それを使用しました。
にしても、コードが汚すぎますね..orz
後できれいにしたいと思います。(「します」じゃないところがミソ)
今回は文字列からXmlDocumentを作成して、ファイルに保存する方法を紹介します。
まずは、以下のようにしてXML文字列を作成します。
PowerShellでは複数行にわたる文字列は ヒア文字列を使用することであらわすことができます。
ヒア文字列は@" ~ "@ で表します。
PS C:\Work> $strXml = @"
>> <?xml version='1.0' ?>
>> <personal_data>
>> <zipcode>012-3456</zipcode>
>> <address>1-1, Tokyo, Japan</address>
>> <name>HIRO</name>
>> </personal_data>
>> "@
>>
どのような文字列が代入されたのかを確認してみると
PS C:\Work> $strXML
<?xml version='1.0' ?>
<personal_data>
<zipcode>012-3456</zipcode>
<address>1-1, Tokyo, Japan</address>
<name>HIRO</name>
</personal_data>
きちんと改行されて代入されていることがわかります
次にこの文字列をXmlDocument型にキャストします。
PS C:\Work> $xmlDoc = [xml]$strXml
最後に、ファイルへ出力する方法ですが、Saveメソッドを使用して下記のように記述します。
PS C:\Work> $xmlDoc.Save("C:\Work\Test.xml")
で、ファイルに出力できたら、メモ帳などで内容を確認してみてください。
下記のようになっているかと思います。
Test.xml
<?xml version="1.0"?>
<personal_data>
<zipcode>012-3456</zipcode>
<address>1-1, Tokyo, Japan</address>
<name>HIRO</name>
</personal_data>
インデントまで自動でしてくれます。
すばらしいですね。
今週は、PowerShellでのXMLの取り扱いについてまとめていこうかと思います。
まずはXMLファイルの読み込みから。
VB.NETだとXmlDocumentは
Dim xmlDoc As New System.Xml.XmlDocument
xmlDoc.Load("C:\Work\Test.xml")
みたいに記述します。
PowerShellでは
[xml]$doc = Get-Content "C:\Work\Test.xml"
と書くと、変数$docにXMLファイルが読み込まれます。
これで読み込むことができるのですが、エンコーディングはきちんと指定することをお勧めします。
エンコーディングを指定する場合は、-encodingパラメータを使用します。
-encodingパラメータには、
- Unicode
- UTF7
- UTF8
- UTF32
- ASCII
- BigEndianUnicode
- Default
- OEM
を指定することができます。
UTF8で読み込む場合は
[xml]$doc = Get-Content "C:\Work\Test.xml" -encoding UTF8
のように記述します。
で、[xml]でキャストした$docのデータ型はどうなっているかというと(GetType()メソッドで確認)
PS C:\Work> $doc.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False XmlDocument System.Xml.XmlNode
XmlDocumentとなっていることが確認できます。
で、使用可能なメンバーは(Get-Memberコマンドレットで確認)
PS C:\Work> $doc | Get-Member
TypeName: System.Xml.XmlDocument
Name MemberType Definition
---- ---------- ----------
ToString CodeMethod static System.String XmlNode(PSObject instance)
add_NodeChanged Method System.Void add_NodeChanged(XmlNodeChangedEventHandler value)
add_NodeChanging Method System.Void add_NodeChanging(XmlNodeChangedEventHandler value)
add_NodeInserted Method System.Void add_NodeInserted(XmlNodeChangedEventHandler value)
add_NodeInserting Method System.Void add_NodeInserting(XmlNodeChangedEventHandler value)
add_NodeRemoved Method System.Void add_NodeRemoved(XmlNodeChangedEventHandler value)
add_NodeRemoving Method System.Void add_NodeRemoving(XmlNodeChangedEventHandler value)
AppendChild Method System.Xml.XmlNode AppendChild(XmlNode newChild)
Clone Method System.Xml.XmlNode Clone()
CloneNode Method System.Xml.XmlNode CloneNode(Boolean deep)
:
たくさんあるので省略
:
このようにPowerShellでは簡単にXMLを取り扱うことが可能です。