パイプ処理と連携することで、Get-ChildItemコマンドレットの結果を特定の条件で絞り込んだり、ソートしたりできる。条件による絞り込みを行うにはWhere-Objectコマンドレットを使用する。特定のキーによるソート処理を行うにはSort-Objectコマンドレットを使用する。取得結果から特定の項目を取得したい、件数を制限したいという場合には、Select-Objectコマンドレットを使用する。
対象ソフトウェア:Windows PowerShell
TIPS「PowerShellのGet-ChildItemコマンドレットでファイル名の一覧を取得する(基本編)」では、Get-ChildItemコマンドレットを使用してファイル一覧を取得する基本的な方法について紹介した。
もっとも、上のTIPSで紹介した内容であれば、あえてPowerShellを持ち出さなくとも、コマンド・プロンプトのdirコマンドでも十分ではないかと思われるかもしれない。しかし、dirコマンドとGet-ChildItemコマンドレットとが決定的に異なる点がある。それは、パイプ処理によってWhere-Object、Sort-Object、Select-Objectなどと連携することで、ファイル・サイズや作成/更新日時などの条件でフォルダやファイルの絞り込みを行ったり、出力する項目を変更したり、あるいは、取得結果を特定のキーでソート処理したりといったことが可能になるという点である。dirコマンドでは対応できなかった柔軟なフィルタリングも、Get-ChildItemコマンドレットを利用することで容易に実現できる。
本TIPSでは、これらのコマンドレットやオプションの使い方について解説する。
まずは、Get-ChildItemコマンドの結果を最終更新日やファイル・サイズなどの条件でもって絞り込む方法だ。これには、Where-Objectコマンドレットを併せて使用する必要がある。Where-Objectは、パイプ経由で渡された入力オブジェクトを特定の条件式で比較し、合致した(Trueと判定された)オブジェクトのみを出力するためのコマンドレットである*1。例えば、以下はマイドキュメント配下で36カ月以上(3年以上)更新されていないファイルだけを検索する例だ。
*1 Where-Objectコマンドレットのエイリアスとして「?」を使用しても構わない。
PS > Get-ChildItem "C:\Documents and Settings\Yamada\My Documents" -Recurse | Where-Object {$_.LastWriteTime -lt (Get-Date).AddMonths(-36)}
ディレクトリ: Microsoft.PowerShell.Core\FileSystem::C:\Documents and Settings\Yamada\My Documents\My Music
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2004/08/18 11:31 542 Sample Music.lnk
ディレクトリ: Microsoft.PowerShell.Core\FileSystem::C:\Documents and Settings\Yamada\My Documents\My Pictures
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2004/08/18 11:31 572 Sample Pictures.lnk
ディレクトリ: Microsoft.PowerShell.Core\FileSystem::C:\Documents and Settings\Yamada\My Documents\php_manual_ja\html
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2005/05/26 20:46 4864 about.generate.html
-a--- 2005/05/26 20:46 3939 about.howtohelp.html
……(以下省略)……
Where-Objectコマンドレットの条件式は、{ } で囲まれたスクリプト・ブロックの内部に記述できる。変数$_は、PowerShell上で利用可能な特殊変数の1つで、パイプ経由で渡されたオブジェクトを表す。例えば、Get-ChildInfoコマンドレットの戻り値は、FileSystemInfoオブジェクト(System.IO名前空間)の配列である。
ここでは、Get-ChildItemコマンドレットから得られたFileInfoオブジェクト群のそれぞれのLastWriteTimeプロパティ(最終更新日)を確認し、その値が今日の36カ月以上前である場合にのみ、そのオブジェクトを出力しているわけだ*2。
*2 AddMonthsメソッドは、Get-Dateコマンドレットによって返されるDateTimeオブジェクトのメソッドで、指定された月数を現在の日付に加算するものだ。
FileInfoオブジェクトで利用可能な主なプロパティは、以下のとおりである。
名前 | 意味 |
---|---|
Attributes | 属性の値(詳細は下表を参照) |
CreationTime | 作成年月日 |
Extension | 拡張子 |
FullName | 絶対パス |
LastAccessTime | 最終アクセス年月日 |
LastWriteTime | 最終更新年月日 |
Length | ファイル・サイズ |
Name | フォルダ/ファイル名 |
FileInfoクラス(System.IO名前空間)で利用可能な主なプロパティ |
Attributesの値 | 意味 |
---|---|
Archive | アーカイブ |
Compressed | 圧縮 |
Directory | フォルダ |
Encrypted | 暗号化 |
Hidden | 隠しファイル |
Normal | 標準のファイル |
ReadOnly | 読み取り専用 |
System | システムファイル |
Temporary | 一時ファイル |
FileInfoクラスのAttributesプロパティの値と意味 |
例えば、ファイル・サイズが1Mbytes以上のものを取得したければ、Lengthプロパティを使って次のように記述する。
PS > Get-ChildItem "C:\Documents and Settings\yamada\My Documents" -Recurse | Where-Object {$_.Length -ge 1MB}
ディレクトリ: Microsoft.PowerShell.Core\FileSystem::C:\Documents and Settings\yamada\My Documents\My Music\My Ripping\200803
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2008/03/04 12:03 47630632 Be My Last.wav
-a--- 2008/03/04 11:34 49683928 Best Friend.wav
-a--- 2008/03/04 11:25 47287240 BLUE FOREST.wav
-a--- 2008/03/04 11:59 55608616 BLUE.wavte
……(以下省略)……
フォルダだけを取得したければ、Attributesプロパティを利用して、次のように記述する。
PS > Get-ChildItem "C:\Documents and Settings\yamada\My Documents" -Recurse | Where-Object {$_.Attributes -eq "Directory"}
ディレクトリ: Microsoft.PowerShell.Core\FileSystem::C:\Documents and Settings\yamada\My Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2008/03/22 1:52 Aptana Studio
d---- 2007/06/12 21:38 Caplio
d---- 2007/06/06 13:34 Cyberlink
d---- 2007/08/29 3:26 Expression
d---- 2007/11/22 22:35 Groove Workspace Templates
……(以下省略)……
取得した結果をソートするのはSort-Objectコマンドレットの役割だ。Sort-Objectコマンドレットもまた、Where-Objectコマンドレットと同様に、パイプ処理の先で利用することを前提としたオブジェクトである。
次の例では、Get-ChildItemコマンドレットによる取得結果をファイル・サイズが大きい順に並べている。
PS > Get-ChildItem C:\Windows | Sort-Object Length -Descending
ディレクトリ: Microsoft.PowerShell.Core\FileSystem::C:\Windows
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2007/08/05 14:25 2137186304 MEMORY.DMP
-a--- 2008/08/12 21:57 1671420 WindowsUpdate.log
-a--- 2008/08/11 0:13 1563176 IIS6.LOG
-ar-- 2004/08/05 21:00 1555860 SET31.tmp
……(以下省略)……
Sort-Objectコマンドレットのパラメータには、ソート・キーとしたいプロパティ名を指定する。この場合は、パイプを経由して渡されたFileInfoオブジェクトのLengthプロパティをキーに降順に(サイズの大きな順に)ソートを行っているわけだ。Sort-Objectコマンドレットはデフォルトで昇順にソート処理を行うが、-Descendingオプションを指定することで降順にソートを行う。
同様の要領で、最終更新日の古い順にファイルを並べたければ、次のように記述する。
PS > Get-ChildItem C:\Windows | Sort-Object LastWriteTime
ディレクトリ: Microsoft.PowerShell.Core\FileSystem::C:\Windows
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 1998/11/12 17:35 306688 IsUn0411.exe
-a--- 2001/09/26 17:53 28672 MMKeybd.dll
-a--- 2002/06/11 7:26 787512 DELL.BMP
-a--- 2004/08/05 21:00 94832 twain.dll
-a--- 2004/08/05 21:00 15360 taskman.exe
……(以下省略)……
最後に、取得する項目(プロパティ)や件数を指定する方法について見ておこう。これを行うのはSelect-Objectコマンドレットの役割である。
例えばGet-ChildItemコマンドレットで取得した結果から、ファイル名と属性、最終アクセス日のみを参照したければ、次のように記述する。
PS > Get-ChildItem C:\Windows | Select-Object Name, Attributes, LastAccessTime
Name Attributes LastAccessTime
---- ---------- --------------
ADDINS Directory 2008/08/13 0:33:46
AppPatch Directory 2008/08/13 2:46:57
ASSEMBLY ReadOnly, System, Directory 2008/08/13 0:33:53
...中略...
BOOTSTAT.DAT System, Archive 2008/08/12 9:58:26
clock.avi Archive 2007/09/17 10:55:51
……(以下省略)……
複数のプロパティを指定する場合には、プロパティ名をカンマ区切りで指定すればよい。
次に、取得する結果件数を絞り込んでみる。例えば以下は、Get-ChildItemコマンドレットによる取得結果をファイル・サイズが大きい順に並べ、先頭の5件のファイル名とサイズを表示する例である。
PS > Get-ChildItem C:\Windows | Sort-Object Length -Descending | Select-Object Name, Length -First 5
Name Length
---- ------
MEMORY.DMP 2137186304
WindowsUpdate.log 1671420
IIS6.LOG 1563176
SET31.tmp 1555860
setupapi.log.0.old 1168187
件数を絞り込むには、-Firstオプションを指定するだけだ。この例では、Sort-Objectコマンドレットによってソートされた結果から先頭の5件を取り出すことができた。ちなみに末尾のnnn件を取得するには、-Firstオプションの代わりに-Last nnnオプションを指定する。
■この記事と関連性の高い別の記事
Copyright© Digital Advantage Corp. All Rights Reserved.