2010年09月08日

[PowerShell] フォルダー一覧・ファイル一覧をそれぞれ取得する

 PowerShellで、指定フォルダー直下のファイルやフォルダーの一覧を取得するには Get-ChildItem コマンドレットを使用します。
人気ブログランキング
PS U:\work\Test> Get-ChildItem


    ディレクトリ: U:\work\Test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2010/09/08      6:52            Folder1
d----        2010/09/08      6:52            Folder2
-a---        2010/09/08      6:53       9069 File1.txt
-a---        2010/09/08      6:54       9236 File2.txt


PS U:\work\Test>

 Get-ChildItemコマンドレットは、フォルダーとファイルの両方を出力します。フォルダーのみ、ファイルのみを出力してほしい場合、Where-Objectコマンドレット( ?{...} )とTest-Path コマンドレットを使用するとうまくいきます。

PS U:\work\Test> # フォルダー一覧
PS U:\work\Test> Get-ChildItem | ?{ Test-Path $_ -PathType Container }


    ディレクトリ: U:\work\Test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2010/09/08      6:52            Folder1
d----        2010/09/08      6:52            Folder2


PS U:\work\Test> # ファイル一覧
PS U:\work\Test> Get-ChildItem | ?{ Test-Path $_ -PathType Leaf }


    ディレクトリ: U:\work\Test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2010/09/08      6:53       9069 File1.txt
-a---        2010/09/08      6:54       9236 File2.txt


PS U:\work\Test>

 出力結果は省略しますが、.NET Frameworkのメソッドを利用して、型名を判定する方法も使用できます。

PS U:\work\Test> Get-ChildItem | ?{ $_.GetType().Name -eq "DirectoryInfo" }
PS U:\work\Test> Get-ChildItem | ?{ $_.GetType().Name -eq "FileInfo" }

 次の方法は@ITに掲載されているものですが、フォルダーによってはうまくいきません。

PS U:\work\Test> Get-ChildItem | ?{ $_.Attributes -eq "Directory" }
PS U:\work\Test> # 何も表示されない。

 これでうまく実行できるフォルダーもあるのですが、たとえばWindowsフォルダーはうまく表示されませんでした。なぜなら、(私の環境では)WindowsフォルダーのAttributes値が"Directory"と等しくないためです。

PS U:\work\Test> (Get-Item 'C:\Windows').Attributes
Directory, NotContentIndexed
PS U:\work\Test> (Get-Item 'C:\Windows').Attributes -eq "Directory"
False
PS U:\work\Test>

 「Attributesが"Directory"と等しい」という条件では駄目だったので、「Attributesが"Directory"を含む」という条件ではどうか確認してみます。

PS U:\work\Test> (Get-Item 'C:\Windows').Attributes -contains "Directory"
False
PS U:\work\Test>

 やっぱり駄目でした。……というのは、Attributesは配列でないためです。enum型なのです。

PS U:\work\Test> (Get-Item 'C:\Windows').Attributes.GetType()

IsPublic IsSerial Name              BaseType
-------- -------- ----              --------
True     True     FileAttributes    System.Enum

 enum型の値は、複数の値についてビットごとのORをとったものです。したがって、ビットごとのANDを計算すれば、AttributesにDirectoryが含まれているかどうかが分かります。

PS U:\work\Test> (Get-Item 'C:\Windows').Attributes -band [System.IO.FileAttributes]::Directory
16
PS U:\work\Test> (Get-Item 'C:\Windows\_default.pif').Attributes -band [System.IO.FileAttributes]::Directory
0

 フォルダーと比較すると結果が16になり、適当なファイルも実験してみたら結果が0になったので、どうやらフォルダーとファイルの区別ができたようです。「16」という値が分かれば、あとはこれで大丈夫です。

PS U:\work\Test> (Get-Item 'C:\Windows').Attributes -band 16
16

 うまくいきました。しかしこの方法を使用すると、何の脈絡もなく「16」という数値が出てくることになります。これをたとえばPowerShellスクリプトに書いたりすると、あとで読んだときに意味が分からなくなりますので、この方法を使用するのは望ましくありません。
web拍手 by FC2
posted by 北条利彦 at 20:26 | Comment(0) | TrackBack(0) | PowerShell | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/161939735

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。