1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PowerShellのパイプライン入門――Get-ChildItem | Where-Object | Select-Objectを理解する

1
Last updated at Posted at 2026-07-10

この記事は以下のシリーズの17番目の記事です。

この記事でやること

PowerShellを使い始めると、次のような書き方をよく見かけます。

Get-ChildItem |
    Where-Object { $_.Extension -eq ".txt" } |
    Select-Object Name, FullName, LastWriteTime

最初は、記号の |$_ が分かりにくいかもしれません。

しかし、この書き方が理解できると、PowerShellでできることが一気に広がります。

この記事では、PowerShellのパイプラインを次の流れで整理します。

コマンド 役割
Get-ChildItem 対象を集める
Where-Object 条件で絞る
Select-Object 必要な項目だけ取り出す
Export-Csv 結果をCSVに出力する

VBS/BAT利用者向けに言うと、PowerShellのパイプラインは、処理対象を次の処理へ順番に渡していく仕組みです。


まず結論

PowerShellの基本的な考え方は、次の形です。

集める | 絞る | 整える | 出力する

ファイル一覧を例にすると、次のようになります。

Get-ChildItem -File |
    Where-Object { $_.Extension -eq ".txt" } |
    Select-Object Name, FullName, LastWriteTime |
    Export-Csv -Path ".\txt_files.csv" -NoTypeInformation -Encoding UTF8

これは次の意味です。

処理 内容
Get-ChildItem -File ファイルを集める
Where-Object .txt だけに絞る
Select-Object 必要な項目だけ選ぶ
Export-Csv CSVに出力する

PowerShellでは、このように処理をつなげて書くことができます。


検証用フォルダを作る

まず、検証用フォルダを作成します。

New-Item -ItemType Directory -Path "C:\work\ps-pipeline-test" -Force
Set-Location "C:\work\ps-pipeline-test"

検証用ファイルを作成します。

Set-Content -Path ".\sample1.txt" -Value "text file 1"
Set-Content -Path ".\sample2.txt" -Value "text file 2"
Set-Content -Path ".\memo.log" -Value "log file"
Set-Content -Path ".\data.csv" -Value "id,name"

サブフォルダも作ります。

New-Item -ItemType Directory -Path ".\sub" -Force
Set-Content -Path ".\sub\subsample.txt" -Value "sub folder text"

確認します。

Get-ChildItem -Recurse

パイプラインとは何か

パイプラインは、コマンドの結果を次のコマンドへ渡す仕組みです。

記号は | です。

コマンドA | コマンドB | コマンドC

これは、次のような意味です。

コマンドAの結果を、コマンドBに渡す。
コマンドBの結果を、コマンドCに渡す。

たとえば、次のコマンドを見ます。

Get-ChildItem | Select-Object Name

これは次の意味です。

Get-ChildItemでファイルやフォルダを取得する。
その結果からNameだけを取り出す。

PowerShellのパイプラインは、単なる文字列ではなく、オブジェクトを渡している点が重要です。


BATのパイプとの違い

BATでも | は使えます。

たとえば、次のような書き方です。

dir | find "txt"

BATの場合、前のコマンドの文字列出力を、次のコマンドへ渡すイメージです。

一方、PowerShellでは、文字列だけでなく、ファイル情報などのオブジェクトを渡します。

たとえば、Get-ChildItem の結果には、次のような情報が含まれています。

プロパティ 内容
Name 名前
FullName フルパス
Extension 拡張子
Length サイズ
CreationTime 作成日時
LastWriteTime 更新日時

そのため、PowerShellでは次のように書けます。

Get-ChildItem -File |
    Where-Object { $_.Extension -eq ".txt" }

文字列に "txt" が含まれるかを見るのではなく、ファイルの Extension プロパティが .txt かどうかを見ています。

ここがPowerShellらしい考え方です。


Get-ChildItemで対象を集める

まずは、ファイルやフォルダの一覧を取得します。

Get-ChildItem

ファイルだけにしたい場合は、-File を付けます。

Get-ChildItem -File

サブフォルダも含めたい場合は、-Recurse を付けます。

Get-ChildItem -File -Recurse

ここでは、Get-ChildItem を「処理対象を集めるコマンド」と考えると分かりやすいです。

まず対象を集める。
そのあとに、絞る・整える・出力する。

Where-Objectで条件に合うものだけ絞る

Where-Object は、条件に合うものだけを残すコマンドです。

.txt ファイルだけに絞る例です。

Get-ChildItem -File |
    Where-Object { $_.Extension -eq ".txt" }

ここで出てくる $_ は、パイプラインで渡されてきた現在の1件を表します。

つまり、次のような意味です。

現在処理中のファイルのExtensionが.txtなら残す

$_.Extension は、現在のファイルの拡張子です。

意味
$_ 現在処理中の1件
$_.Name 現在のファイル名
$_.Extension 現在の拡張子
$_.Length 現在のファイルサイズ
$_.LastWriteTime 現在の更新日時

条件式の基本

PowerShellでは、比較に次のような演算子を使います。

演算子 意味
-eq 等しい $_.Extension -eq ".txt"
-ne 等しくない $_.Extension -ne ".log"
-gt より大きい $_.Length -gt 1MB
-lt より小さい $_.Length -lt 1MB
-ge 以上 $_.Length -ge 1MB
-le 以下 $_.Length -le 1MB
-like ワイルドカード一致 $_.Name -like "*.txt"
-match 正規表現一致 $_.Name -match "sample"

たとえば、1KBより大きいファイルを抽出する場合です。

Get-ChildItem -File |
    Where-Object { $_.Length -gt 1KB }

名前に sample を含むファイルを抽出する場合です。

Get-ChildItem -File |
    Where-Object { $_.Name -like "*sample*" }

30日以上更新されていないファイルを抽出する場合です。

Get-ChildItem -File -Recurse |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) }

Select-Objectで必要な項目だけ取り出す

Select-Object は、必要なプロパティだけを取り出すコマンドです。

Get-ChildItem -File |
    Select-Object Name, FullName, Length, LastWriteTime

これにより、ファイル情報のうち、必要な項目だけを表示できます。

Where-Object と組み合わせると、次のようになります。

Get-ChildItem -File |
    Where-Object { $_.Extension -eq ".txt" } |
    Select-Object Name, FullName, Length, LastWriteTime

意味は次の通りです。

ファイルを集める。
.txtだけに絞る。
Name, FullName, Length, LastWriteTimeだけ表示する。

計算した列を追加する

Select-Object では、計算した列を追加できます。

ファイルサイズをMBで表示する例です。

Get-ChildItem -File -Recurse |
    Select-Object Name,
                  FullName,
                  @{Name="SizeMB"; Expression={[math]::Round($_.Length / 1MB, 2)}},
                  LastWriteTime

この部分で、SizeMB という列を作っています。

@{Name="SizeMB"; Expression={[math]::Round($_.Length / 1MB, 2)}}

Length はバイト単位なので、1MB で割ってMB単位にしています。


Export-CsvでCSVに出力する

パイプラインの最後に Export-Csv をつなげると、結果をCSVに出力できます。

Get-ChildItem -File -Recurse |
    Where-Object { $_.Extension -eq ".txt" } |
    Select-Object Name, FullName, Length, LastWriteTime |
    Export-Csv -Path ".\txt_files.csv" -NoTypeInformation -Encoding UTF8

これで、.txt ファイルだけをCSVに出力できます。

Excelで開く前提なら、環境によっては utf8BOM を検討します。

Export-Csv -Path ".\txt_files.csv" -NoTypeInformation -Encoding utf8BOM

Windows PowerShell 5.1で古いExcel向けなら、Default を使うこともあります。

Export-Csv -Path ".\txt_files.csv" -NoTypeInformation -Encoding Default

Sort-Objectで並べ替える

パイプラインの途中に Sort-Object を入れると、並べ替えができます。

更新日時の新しい順に並べる例です。

Get-ChildItem -File -Recurse |
    Sort-Object LastWriteTime -Descending |
    Select-Object Name, FullName, LastWriteTime

ファイルサイズの大きい順に並べる例です。

Get-ChildItem -File -Recurse |
    Sort-Object Length -Descending |
    Select-Object Name, FullName, Length

このように、PowerShellでは処理を追加したい場所にコマンドを差し込めます。

集める | 絞る | 並べる | 整える | 出力する

パイプラインを読みやすく書く

PowerShellのコマンドは、1行で書くこともできます。

Get-ChildItem -File -Recurse | Where-Object { $_.Extension -eq ".txt" } | Select-Object Name, FullName, LastWriteTime | Export-Csv -Path ".\txt_files.csv" -NoTypeInformation -Encoding UTF8

ただし、長くなると読みにくくなります。

実務では、次のように改行して書くと読みやすいです。

Get-ChildItem -File -Recurse |
    Where-Object { $_.Extension -eq ".txt" } |
    Select-Object Name, FullName, LastWriteTime |
    Export-Csv -Path ".\txt_files.csv" -NoTypeInformation -Encoding UTF8

パイプ | の位置で改行すると、処理の流れが見えやすくなります。


foreachとの違い

PowerShellでは、foreach を使って1件ずつ処理することもできます。

$files = Get-ChildItem -File

foreach ($file in $files) {
    Write-Host $file.Name
}

一方、パイプラインでは次のように書けます。

Get-ChildItem -File |
    ForEach-Object {
        Write-Host $_.Name
    }

どちらも使えます。

簡単に考えるなら、次のように使い分けるとよいです。

書き方 向いている用途
パイプライン 絞る、並べる、項目を選ぶ、CSV出力
foreach 複数行の複雑な処理、件数管理、try/catch

たとえば、CSV出力だけならパイプラインが簡潔です。

Get-ChildItem -File |
    Select-Object Name, FullName |
    Export-Csv ".\files.csv" -NoTypeInformation -Encoding UTF8

一方、1件ずつコピーして成功件数・失敗件数を数えるなら、foreach の方が分かりやすい場合があります。


よくあるパイプラインの型

実務でよく使う型をいくつか整理します。

ファイル一覧をCSV出力する

Get-ChildItem -Path ".\" -File -Recurse |
    Select-Object Name, FullName, Length, LastWriteTime |
    Export-Csv -Path ".\file_list.csv" -NoTypeInformation -Encoding UTF8

特定拡張子だけ出力する

Get-ChildItem -Path ".\" -File -Recurse |
    Where-Object { $_.Extension -eq ".log" } |
    Select-Object Name, FullName, LastWriteTime |
    Export-Csv -Path ".\log_files.csv" -NoTypeInformation -Encoding UTF8

古いファイルを抽出する

Get-ChildItem -Path ".\" -File -Recurse |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
    Select-Object Name, FullName, LastWriteTime |
    Export-Csv -Path ".\old_files.csv" -NoTypeInformation -Encoding UTF8

大きいファイル順に出力する

Get-ChildItem -Path ".\" -File -Recurse |
    Sort-Object Length -Descending |
    Select-Object Name,
                  FullName,
                  @{Name="SizeMB"; Expression={[math]::Round($_.Length / 1MB, 2)}} |
    Export-Csv -Path ".\large_files.csv" -NoTypeInformation -Encoding UTF8

やってはいけない例

パイプラインの途中で何を渡しているか分からない

長い処理を書くと、途中で何が渡っているか分からなくなることがあります。

その場合は、途中まで実行して確認します。

Get-ChildItem -File -Recurse

次に、絞り込みまで確認します。

Get-ChildItem -File -Recurse |
    Where-Object { $_.Extension -eq ".txt" }

最後に、項目選択やCSV出力を追加します。

Get-ChildItem -File -Recurse |
    Where-Object { $_.Extension -eq ".txt" } |
    Select-Object Name, FullName, LastWriteTime

一気に書かず、左から順番に確認すると分かりやすいです。


何でも1行で書く

次のような1行コマンドは、動きますが読みにくいです。

Get-ChildItem -File -Recurse | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } | Select-Object Name, FullName, LastWriteTime | Export-Csv ".\old.csv" -NoTypeInformation -Encoding UTF8

実務では、次のように改行した方が読みやすいです。

Get-ChildItem -File -Recurse |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
    Select-Object Name, FullName, LastWriteTime |
    Export-Csv ".\old.csv" -NoTypeInformation -Encoding UTF8

削除処理をいきなりつなげる

危険なのは、抽出した結果をそのまま削除する場合です。

Get-ChildItem -File -Recurse |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
    Remove-Item

このような処理は、まず -WhatIf を付けます。

Get-ChildItem -File -Recurse |
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
    Remove-Item -WhatIf

削除対象を確認してから、-WhatIf を外します。

PowerShellのパイプラインは強力なので、削除や移動の前には必ず確認する習慣をつけた方が安全です。


実務で使いやすいテンプレート

ファイル一覧を条件で絞り、CSVに出力するテンプレートです。

$targetDir = Join-Path $PSScriptRoot "target"
$outputDir = Join-Path $PSScriptRoot "output"

New-Item -ItemType Directory -Path $outputDir -Force | Out-Null

$today = Get-Date -Format "yyyyMMdd"
$outputPath = Join-Path $outputDir "file_list_$today.csv"

Get-ChildItem -Path $targetDir -File -Recurse |
    Where-Object { $_.Extension -eq ".txt" } |
    Sort-Object LastWriteTime -Descending |
    Select-Object Name,
                  FullName,
                  Extension,
                  @{Name="SizeKB"; Expression={[math]::Round($_.Length / 1KB, 2)}},
                  LastWriteTime |
    Export-Csv -Path $outputPath -NoTypeInformation -Encoding UTF8

このテンプレートは、次の流れになっています。

target配下のファイルを集める
.txtだけに絞る
更新日時の新しい順に並べる
必要な項目だけ選ぶ
CSVに出力する

まとめ

この記事では、PowerShellのパイプラインについて整理しました。

パイプラインは、コマンドの結果を次のコマンドへ渡す仕組みです。

基本形は次の通りです。

Get-ChildItem |
    Where-Object { 条件 } |
    Select-Object 項目 |
    Export-Csv 出力先

実務では、次のように考えると分かりやすいです。

集める | 絞る | 並べる | 整える | 出力する

代表的なコマンドは次の通りです。

コマンド 役割
Get-ChildItem 対象を集める
Where-Object 条件で絞る
Sort-Object 並べる
Select-Object 必要な項目を選ぶ
Export-Csv CSVに出力する
ForEach-Object 1件ずつ処理する

VBS/BATからPowerShellに移るときに重要なのは、PowerShellでは文字列だけでなく、オブジェクトを次の処理へ渡しているという点です。

そのため、ファイル名の文字列を無理に解析するのではなく、NameFullNameExtensionLengthLastWriteTime などのプロパティを使って処理できます。

PowerShellのパイプラインを理解すると、ファイル一覧作成、CSV出力、ログ調査、古いファイル抽出、バックアップ対象確認などの処理がかなり書きやすくなります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?