7

PowerShell から、ファイル パスが特定のディレクトリ (またはそのサブディレクトリの 1 つ) にあるかどうかを確認したいと考えています。

今、私はやっています:

$file.StartsWith(  $directory, [StringComparison]::InvariantCultureIgnoreCase )

しかし、もっと良い方法があると確信しています。

$file.Directoryすべての s を取得して反復することもでき.Parentましたが、もっと単純なものを望んでいました。

EDIT : ファイルが存在しない可能性があります。パスばかり見てます。

4

5 に答える 5

6

次のような単純なものはどうでしょうか。

PS> gci . -r foo.txt

これは、foo.txt をフィルターとして指定する -filter パラメーターを (位置によって) 暗黙的に使用します。*.txt または foo?.txt を指定することもできます。StartsWith の問題は、大文字と小文字を区別しない比較を処理している間、/ と \ の両方が PowerShell で有効なパス区切り文字であるという問題がまだあることです。

ファイルが存在しない可能性があり、 $file と $directory の両方が絶対パスであると仮定すると、これを "PowerShell" の方法で実行できます。

(Split-Path $file -Parent) -replace '/','\' -eq (Get-Item $directory).FullName

ただし、パス / -> \ を正規化する必要があるため、これは素晴らしいことではありませんが、少なくとも PowerShell 文字列比較では大文字と小文字が区別されません。別のオプションは、IO.Path を使用してパスを正規化することです。

[io.path]::GetDirectoryName($file) -eq [io.path]::GetFullPath($directory)

これに関する 1 つの問題は、GetFullPath がプロセスの現在のディレクトリに基づいて相対パスを絶対パスにすることです。これは、多くの場合、PowerShell の現在のディレクトリと同じではありません。したがって、「$pwd\$directory」のように指定する必要がある場合でも、$directory が絶対パスであることを確認してください。

于 2009-06-23T00:44:48.193 に答える
2

パスが存在しない可能性があるため、string.StartsWithこのタイプのテストを行うには を使用しても問題ありません (ただしOrdinalIgnoreCase、ファイル システムがパスを比較する方法をより適切に表しています)。

唯一の注意点は、パスが正規の形式である必要があることです。C:\x\..\a\b.txtそうしないと、およびのようなパスC:/a/b.txtは、「これはディレクトリの下にありますかC:\a\」テストに失敗します。テストを実行する前に、静的Path.GetFullPathメソッドを使用してパスの完全な名前を取得できます。

function Test-SubPath( [string]$directory, [string]$subpath ) {
  $dPath = [IO.Path]::GetFullPath( $directory )
  $sPath = [IO.Path]::GetFullPath( $subpath )
  return $sPath.StartsWith( $dPath, [StringComparison]::OrdinalIgnoreCase )
}

また、これは論理的な包含をカバーしていないことに注意してください (たとえば、 に\\some\network\path\マッピングされている場合、 を介してファイルにアクセスできる場合でも、が下にZ:\path\あるかどうかのテストは失敗します)。この動作をサポートする必要がある場合は、これらの質問が役立つ場合があります。\\some\network\path\b.txtZ:\Z:\path\b.txt

于 2009-11-14T14:04:25.137 に答える
0

本当に簡単なこと:

14:47:28 PS>pwd

C:\Documents and Settings\me\Desktop

14:47:30 PS>$path = pwd

14:48:03 PS>$path

C:\Documents and Settings\me\Desktop

14:48:16 PS>$files = Get-ChildItem $path -recurse | 
                     Where {$_.Name -match "thisfiledoesnt.exist"}

14:50:55 PS>if ($files) {write-host "the file exists in this path somewhere"
            } else {write-host "no it doesn't"}
no it doesn't

(デスクトップまたはデスクトップ上のフォルダーに新しいファイルを作成し、「thisfileexists.txt」という名前を付けます)

14:51:03 PS>$files = Get-ChildItem $path -recurse | 
                     Where {$_.Name -match "thisfileexists.txt"}

14:52:07 PS>if($files) {write-host "the file exists in this path somewhere"
            } else {write-host "no it doesn't"}
the file exists in this path somewhere

もちろん、反復はまだ行われていますが、PS が代わりにそれを行っています。システム/隠しファイルを探す場合は、-force も必要になる場合があります。

于 2009-06-22T22:02:22.293 に答える
0

このようなもの?

Get-ChildItem -Recurse $directory | Where-Object { $_.PSIsContainer -and `
    $_.FullName -match "^$($file.Parent)" } | Select-Object -First 1
于 2009-06-23T18:12:07.037 に答える