PowerShell相対パスで指定したフォルダを除外したファイル群の処理1/2

Windows に標準搭載されている、マイクロソフトが開発した .NET フレームワークが利用できるオブジェクト指向のコマンドラインインタプリタ (CLI) PowerShell で、配列に指定した相対パスのフォルダのファイルを除外して、存在する拡張子を表示するプログラム例実行結果を紹介します。

PowerShell 相対パスで指定したフォルダを除外したファイル群の処理1

※ Windows PowerShell 5.1.19041.5965 を使用します。
※プログラムは自己責任でご利用ください。

前回の記事

前回は、カレントディレクトリ内のファイルの拡張子を列挙するプログラムで、指定した拡張子だけを除外するプログラム例と実行結果を紹介しました。

今回は、このプログラムに、前述した、指定した相対パスのフォルダのファイルを除外する処理を追加します。

指定した相対パスのフォルダを除外する実装例

以下は、前回のプログラムをベースに、指定した相対パスのフォルダ群を除外する機能を追加したものです。
※ハイライトの行が追加した部分です。

# 除外するフォルダ、拡張子を指定します。
$excludeDirsRelative = @('./output', './build')  # 相対パスで指定
$excludeExtensions = @('.dll', '.fnt')  # 拡張子の除外リスト

# フォルダパス $dir は、除外するフォルダパスのリスト $excludeDirs に含まれているか確認します。
function IsExcluded($dir, $excludeDirs) {
    $fullPath = [System.IO.Path]::GetFullPath($dir)
    return $excludeDirs | Where-Object { $fullPath -like "$_*" }
}

#-relativePaths パラメータに割り当てた配列の全ての相対パスを絶対パスに変換した配列を返します。
# 変換に失敗したパスは返り値の配列に含まれません。
function DirsRelativeToAbsolute {
    param (
        [string[]]$relativePaths
    )
    return $relativePaths | ForEach-Object {
        try {
            [System.IO.Path]::GetFullPath((Resolve-Path -LiteralPath $_).ProviderPath)
        } catch {
            Write-Warning "除外対象のパス '$_' が見つかりませんでした。スキップします。"
            $null
        }
    } | Where-Object { $_ -ne $null }
}

# $excludeDirsRelative で指定された除外するフォルダパスを上記関数で絶対パスに変換して格納します。
$excludeDirs = DirsRelativeToAbsolute -relativePaths $excludeDirsRelative

# 除外するフォルダ、拡張子を除いた、カレントディレクトリ以下に含まれる拡張子を表示します。
Get-ChildItem -Recurse -File -Force |
    Where-Object {
        $_.FullName -notmatch '\\\.git\\' -and
        -not (IsExcluded $_.DirectoryName $excludeDirs) -and
        $_.Extension -ne '' -and
        $_.Extension -notin $excludeExtensions
    } |
    Select-Object -ExpandProperty Extension |
    ForEach-Object { $_.TrimStart('.') } |
    Sort-Object -Unique |
    ForEach-Object { Write-Host "*.$_" }

追加した関数などの単位で、処理の流れを説明します。

IsExcluded 関数の処理

# フォルダパス $dir が、$excludeDirs の要素のフォルダまたは下位のフォルダの場合はオブジェクトを返し、該当しない場合は $null を返します。
function IsExcluded($dir, $excludeDirs) {
    $fullPath = [System.IO.Path]::GetFullPath($dir)
    return $excludeDirs | Where-Object { $fullPath -like "$_*" }
}

IsExcluded 関数では

  • フォルダパスの文字列が格納された $dir 引数
  • 除外するフォルダの絶対パスの配列 $excludeDirs 引数

を受け取り、$dir のフォルダパスを GetFullPath 関数で絶対パスに変換して結果を $fullPath 変数に格納します。

指定したパス文字列の絶対パスを返します。

Path.GetFullPath メソッド (System.IO) | Microsoft Learn

return の部分では、$excludeDirs に格納されている配列の「除外するフォルダの絶対パス」の要素1つずつを Where-Object コマンドレットに渡し、 -like パラメータで「除外するフォルダの絶対パス」と $fullPath の最初から途中までが一致しているかワイルドカード * を指定して判定します。

-Like

プロパティ値がワイルドカード文字 (*) を含む値と一致する場合に、このコマンドレットがオブジェクトを取得することを示します。

Where-Object (Microsoft.PowerShell.Core) – PowerShell | Microsoft Learn

例えば C:/exclude/dir が「除外するフォルダの絶対パス」の場合、$fullPath に C:/exclude/dir/hoge.txt など、前半が一致するものは、オブジェクトとして取得され、戻り値の要素に加わります。

除外するフォルダ群と全く一致しない場合は、 $null が返ります。

DirsRelativeToAbsolute 関数の処理

#-relativePaths パラメータに割り当てた配列の全ての相対パスを絶対パスに変換した配列を返します。
# 変換に失敗したパスは返り値の配列に含まれません。
function DirsRelativeToAbsolute {
    param (
        [string[]]$relativePaths
    )
    return $relativePaths | ForEach-Object {
        try {
            [System.IO.Path]::GetFullPath((Resolve-Path -LiteralPath $_).ProviderPath)
        } catch {
            Write-Warning "除外対象のパス '$_' が見つかりませんでした。スキップします。"
            $null
        }
    } | Where-Object { $_ -ne $null }
}

関数の引数(パラメータ)定義とその呼び出し方

param には、受け取る引数(パラメータ)を指定できます。
※オプションのように見えた Get-ChildItem -File の -File などは、それを指定しただけで値が変わる switch パラメータです。

パラメーターとは、関数またはスクリプト ブロックの param() ステートメントで宣言された変数です。

about_Functions_Advanced_Parameters – PowerShell | Microsoft Learn

上記の関数は、以下で呼び出されます。

# $excludeDirsRelative で指定された除外するフォルダパスを上記関数で絶対パスに変換して格納します。
$excludeDirs = DirsRelativeToAbsolute -relativePaths $excludeDirsRelative

param で指定された引数(パラメータ)は、上記の関数呼び出しのように「-パラメータ名 値」の形式の名前付きパラメータとしても、 param で定義された順に変数や値を割り当てる位置指定パラメータとしても関数に渡すことができます。

すべてのコマンドレット パラメーターは、名前付きパラメーターまたは位置指定パラメーターです。 名前付きパラメーターでは、コマンドレットを呼び出すときにパラメーター名と引数を入力する必要があります。 位置指定パラメーターでは、引数を相対的な順序で入力するだけで済みます。

コマンドレット パラメーターの種類 – PowerShell | Microsoft Learn

渡された配列の要素を順次処理

    return $relativePaths | ForEach-Object {
        try {
            [System.IO.Path]::GetFullPath((Resolve-Path -LiteralPath $_).ProviderPath)
        } catch {
            Write-Warning "除外対象のパス '$_' が見つかりませんでした。スキップします。"
            $null
        }
    } | Where-Object { $_ -ne $null }

「return $relativePaths | あとの処理」により、 $relativePaths 引数(パラメータ)の配列要素「相対フォルダパス」の文字列のオブジェクトを、|(パイプ) で連結した「あとの処理1つずつ渡して処理して、その結果の配列が返されます。

ForEach-Object コマンドレットでは、渡されたオブジェクト1つずつに処理を行います。
例では GetFullPath 関数で相対パスの文字列を、絶対パスの文字列変換して、その文字列オブジェクトを | (パイプ)で連結した後の処理に渡します。

指定したパス文字列の絶対パスを返します。

Path.GetFullPath メソッド (System.IO) | Microsoft Learn

GetFullPath 関数は、パスの表記と異なる文字列などが渡されて変換できない場合例外を throw するので、 try ブロックで囲んで処理を行い、例外が throw された場合は catch ブロックで捕らえて、エラーメッセージを表示します。

trycatch、およびfinally ブロックを使用して、スクリプト内の終了エラーに応答または処理します。

about_Try_Catch_Finally – PowerShell | Microsoft Learn

エラーが起きた際は空を表す $null を | (パイプ) で連結した次の処理に渡します。

NULL は、不明または空の値と考えることができます。 変数は、値またはオブジェクトを割り当てるまで NULL です。 これは、値を必要とし、値が NULL の場合にエラーを生成するいくつかのコマンドがあるため、重要な場合があります。

PowerShell の$null

$null は、NULL を表すために使用される PowerShell の自動変数です。 これを変数に割り当て、比較で使用し、コレクション内の NULL のプレース ホルダーとして使用できます。

$nullについて知りたいこと – PowerShell | Microsoft Learn

空の文字列以外を戻り値の要素に追加

    } | Where-Object { $_ -ne $null }

Where-Object コマンドレットで -ne パラメータで渡されたオブジェクト $_ を $null と比較して、先ほどの処理で絶対パスが得られなかった場合に渡される、空の文字列以外を選別して、次の処理に渡します。

-NE

Indicates that this cmdlet gets objects if the property value is different than the specified value.

プロパティ値が指定された値と異なる場合に、このコマンドレットがオブジェクトを取得することを示します。

Where-Object (Microsoft.PowerShell.Core) – PowerShell | Microsoft Learn と Google 翻訳

今回は次の処理がないため、 return で返却される要素として、空の文字列以外の文字列オブジェクトが戻り値に追加されます。

$excludeDirs に、絶対パスの除外するフォルダパス群を格納

# $excludeDirsRelative で指定された除外するフォルダパスを上記関数で絶対パスに変換して格納します。
$excludeDirs = DirsRelativeToAbsolute -relativePaths $excludeDirsRelative

以上の関数呼び出しの結果、 $excludeDirsRelative に格納されている相対パスのフォルダパス(例では ‘./output’, ‘./build’ ) を、絶対パスに変換した、除外する絶対フォルダパス文字列を要素に持つ配列$excludeDirs 変数格納されました。

今回はここまで

次回に続きます。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました