web-dev-qa-db-ja.com

Get-ChildItem -excludeを使用して複数のフォルダーを除外するにはどうすればよいですか?

Pro/Engineer CADシステムの構成ファイルを生成する必要があります。サーバー上の特定のドライブからのフォルダーの再帰リストが必要です。ただし、 'ARCHIVEですべてのフォルダーを除外する必要があります'さまざまな異なるケースを含む。

私はそれがフォルダを除外しないことを除いて機能する以下を書いた!!

$folder = "T:\Drawings\Design\*"
$raw_txt = "T:\Design Projects\Design_Admin\PowerShell\raw.txt"
$search_pro = "T:\Design Projects\Design_Admin\PowerShell\search.pro"
$archive = *archive*,*Archive*,*ARCHIVE*

Get-ChildItem -Path $folder -Exclude $archive -Recurse  | where {$_.Attributes -match 'Directory'}  | ForEach-Object {$_.FullName} > $search_pro   
40
peterjfrancis

私はこのようにします:

Get-ChildItem -Path $folder -r  | 
          ? { $_.PsIsContainer -and $_.FullName -notmatch 'archive' }
34
CB.

この回答が以前の回答の重複と思われる場合は申し訳ありません。これを解決する最新の(POSH 5.0でテスト済み)方法を示したかっただけです。以前の回答は3.0以前で、最新のソリューションほど効率的ではありませんでした。

ドキュメント はこれについて明確ではありませんが、_Get-ChildItem -Recurse -Exclude_は、親パス(_Split-Path $_.FullName -Leaf_)ではなく、リーフ(_Split-Path $_.FullName -Parent_)の除外のみに一致します。除外と一致すると、一致する葉を持つアイテムが削除されます。 _Get-ChildItem_は引き続きそのリーフに再帰します。

POSH 1.0または2.0

_Get-ChildItem -Path $folder -Recurse  | 
          ? { $_.PsIsContainer -and $_.FullName -inotmatch 'archive' }
_

注:同じ @ CBとして回答 =。

POSH 3.0以降

_Get-ChildItem -Path $folder -Directory -Recurse  | 
          ? { $_.FullName -inotmatch 'archive' }
_

注:更新済み @ CBからの回答 =。

複数の除外

これは特に、Excludeパラメーターでリーフを除外し、ilike(大文字と小文字を区別しない)比較で親を除外しながら、ディレクトリをターゲットにします。

_#Requires -Version 3.0
[string[]]$Paths = @('C:\Temp', 'D:\Temp')
[string[]]$Excludes = @('*archive*', '*Archive*', '*ARCHIVE*', '*archival*')

$files = Get-ChildItem $Paths -Directory -Recurse -Exclude $Excludes | %{ 
    $allowed = $true
    foreach ($exclude in $Excludes) { 
        if ((Split-Path $_.FullName -Parent) -ilike $exclude) { 
            $allowed = $false
            break
        }
    }
    if ($allowed) {
        $_
    }
}
_

注:_$Excludes_で大文字と小文字を区別する場合、2つの手順があります。

  1. _Get-ChildItem_からExcludeパラメーターを削除します。
  2. 最初のif条件を次のように変更します:
    • if ($_.FullName -clike $exclude) {

注:このコードには冗長性があり、実稼働では決して実装しません。正確なニーズに合わせて、これをかなり単純化する必要があります。詳細な例として役立ちます。

30
VertigoRay

いくつかのフォルダーをスキップする私の[〜#〜] kiss [〜#〜]アプローチはGet-ChildItem呼び出し。これにより、ルートレベルのフォルダーは除外されますが、必要に応じてより深いレベルのフォルダーは除外されません。

Get-ChildItem -Exclude folder1,folder2 | Get-ChildItem -Recurse | ...
  • 開始除外不要なフォルダー
  • 次に、不要なフォルダを除外してrecursive検索を実行します。

このアプローチで私が気に入っているのは、シンプルで覚えやすいことです。最初の検索でフォルダーとファイルを混在させたくない場合は、フィルターが必要になります。

25
guillem

除外パターンshouldは大文字と小文字を区別しないため、除外のすべてのケースを指定する必要はありません。

つまり、_-Exclude_パラメーターは文字列の配列を受け入れるため、_$archive_をそのように定義している限り、設定する必要があります。

$archive = ("*archive*","*Archive*","*ARCHIVE*");

また、末尾のアスタリスクを_$folder_から削除する必要があります-_-recurse_を指定しているため、トップレベルのフォルダーのみを指定する必要があります。

_$folder = "T:\Drawings\Design\"_

完全に改訂されたスクリプト。これにより、ディレクトリが見つかったかどうかの検出方法も変更され、プロパティを直接プルしてすべてをファイルにダンプできるため、_Foreach-Object_がスキップされます。

_$folder = "T:\Drawings\Design\";
$raw_txt = "T:\Design Projects\Design_Admin\PowerShell\raw.txt";
$search_pro = "T:\Design Projects\Design_Admin\PowerShell\search.pro";
$archive = ("*archive*","*Archive*","*ARCHIVE*");

Get-ChildItem -Path $folder -Exclude $archive -Recurse  | where {$_.PSIsContainer}  | select-Object -expandproperty FullName |out-file $search_pro 
_
14
alroc

私はこれがかなり古いことを知っています-しかし、簡単な解決策を探して、このスレッドを見つけました...質問が正しければ、Get-ChildItemを使用して複数のディレクトリをリストする方法を探していました。 powershell 5.0を使用したはるかに簡単な方法があるようです-例

Get-ChildItem -Path D:\ -Directory -Name -Exclude tmp,music
   chaos
   docs
   downloads
   games
   pics
   videos

-Exclude句がなければ、tmpとmusicはそのリストに残ります。 -Nameを使用しない場合、Get-ChildItemの詳細な出力のため、-Exclude句は機能しません。これが特定の名前なしですべてのディレクトリ名をリストする簡単な方法を探している一部の人々を助けることを願っています...

乾杯

5
lil

VertigoRayは、彼の答えで、-Excludeはパスのリーフレベルでのみ機能すると説明しました(ファイルの場合はパスが削除されたファイル名、サブディレクトリの場合はパスが削除されたディレクトリ名)。したがって、-Excludeを使用してディレクトリ(「bin」など)を指定し、そのディレクトリ内のすべてのファイルとサブディレクトリを除外することはできません。

1つ以上のディレクトリのファイルとサブディレクトリを除外する関数を次に示します(これが質問に直接答えているわけではないことは知っていますが、-Excludeの制限を回避するのに役立つと思います)。

$rootFolderPath = 'C:\Temp\Test'
$excludeDirectories = ("bin", "obj");

function Exclude-Directories
{
    process
    {
        $allowThrough = $true
        foreach ($directoryToExclude in $excludeDirectories)
        {
            $directoryText = "*\" + $directoryToExclude
            $childText = "*\" + $directoryToExclude + "\*"
            if (($_.FullName -Like $directoryText -And $_.PsIsContainer) `
                -Or $_.FullName -Like $childText)
            {
                $allowThrough = $false
                break
            }
        }
        if ($allowThrough)
        {
            return $_
        }
    }
}

Clear-Host

Get-ChildItem $rootFolderPath -Recurse `
    | Exclude-Directories

ディレクトリツリーの場合:

C:\Temp\Test\
|
|_SomeFolder\
|  |
|  |_bin (file)
|
|_MyApplication\
  |
  |_BinFile.txt
  |_FileA.txt
  |_FileB.txt
  |
  |_bin\
    |
    |_Debug\
      |
      |_SomeFile.txt

結果は次のとおりです。

C:\Temp\Test\
|
|_SomeFolder\
|  |
|  |_bin (file)
|
|_MyApplication\
  |
  |_BinFile.txt
  |_FileA.txt
  |_FileB.txt

Bin \サブフォルダーとそのすべてのコンテンツは除外されますが、ファイルBin.txtまたはbin(拡張子のない「bin」という名前のファイル)は除外されません。

1
Simon Tewsi

このように、正規表現の「または」記号を除外できます。これは、除外するフォルダーと同じ名前のファイルが必要ないことを前提としています。

$exclude = 'dir1|dir2|dir3'
ls -r | where { $_.fullname -notmatch $exclude }

ls -r -dir | where fullname -notmatch 'dir1|dir2|dir3'
0
js2010