it-swarm.com.de

Wie kann ich mehrere Ordner mit Get-ChildItem -exclude ausschließen?

Ich muss eine Konfigurationsdatei für unser Pro/Engineer CAD System erstellen. Ich brauche eine rekursive Liste der Ordner von einem bestimmten Laufwerk auf unserem Server. Ich muss jedoch jeden Ordner mit 'ARCHIVE' EXCLUDE einschließlich der verschiedenen Fälle ausschließen.

Ich habe folgendes geschrieben, was funktioniert, außer dass es die Ordner nicht ausschließt !! 

$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   
35
peterjfrancis

Ich würde es so machen:

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

Ich entschuldige mich, wenn diese Antwort wie eine Verdoppelung früherer Antworten erscheint. Ich wollte nur einen aktualisierten (mit POSH 5.0 getesteten) Lösungsweg zeigen. Die vorherigen Antworten waren vor 3.0 und nicht so effizient wie moderne Lösungen.

Die Dokumentation ist hier nicht klar, aber Get-ChildItem -Recurse -Exclude Stimmt nur mit dem Ausschluss auf dem Blatt überein (Split-Path $_.FullName -Leaf), Nicht mit dem übergeordneten Pfad (Split-Path $_.FullName -Parent) . Wenn Sie den Ausschluss abgleichen, wird nur der Artikel mit dem passenden Blatt entfernt. Get-ChildItem Wird weiterhin in dieses Blatt zurückkehren.

In POSH 1.0 oder 2.0

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

Hinweis: Gleiches Antwort als @CB . =

In POSH 3.0+

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

Hinweis: Aktualisiert Antwort von @CB . =

Mehrere Ausschlüsse

Dies zielt speziell auf Verzeichnisse ab, während Blätter mit dem Parameter Exclude und Eltern mit dem Vergleich ilike (ohne Berücksichtigung der Groß-/Kleinschreibung) ausgeschlossen werden:

#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) {
        $_
    }
}

Hinweis: Wenn bei $Excludes Zwischen Groß- und Kleinschreibung unterschieden werden soll, gibt es zwei Schritte:

  1. Entfernen Sie den Parameter Exclude aus Get-ChildItem.
  2. Ändern Sie die erste if Bedingung in:
    • if ($_.FullName -clike $exclude) {

Hinweis: Dieser Code verfügt über Redundanz, die ich niemals in der Produktion implementieren würde. Sie sollten dies ein wenig vereinfachen, um es genau Ihren Bedürfnissen anzupassen. Es dient als ausführliches Beispiel.

30
VertigoRay

Mein KISS -Ansatz, um einige Ordner zu überspringen, ist die Verkettung von Get-ChildItem-Aufrufen. Dies schließt Ordner der Stammebene aus, nicht jedoch Ordner der tieferen Ebene, wenn Sie dies möchten.

Get-ChildItem -Exclude folder1,folder2 | Get-ChildItem -Recurse | ...
  • Starten Sie ausgenommen Ordner, die Sie nicht möchten 
  • Führen Sie dann die rekursive Suche durch, wobei nicht gewünschte Ordner ausgeschlossen sind.

Was mir an diesem Ansatz gefällt, ist, dass es einfach und leicht zu merken ist. Wenn Sie bei der ersten Suche keine Ordner und Dateien mischen möchten, ist ein Filter erforderlich.

17
guillem

Das Ausschlussmuster sollte ohne Berücksichtigung der Groß- und Kleinschreibung, sodass Sie nicht jeden Fall für den Ausschluss angeben müssen.

Allerdings akzeptiert der Parameter -Exclude ein Array von Zeichenfolgen. Solange Sie $archive als solche definieren, sollten Sie festgelegt sein.

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

Sie sollten auch den abschließenden Stern aus $folder entfernen - da Sie -recurse angeben, müssen Sie nur den Ordner der obersten Ebene angeben.

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

Vollständig überarbeitetes Skript. Dies ändert auch, wie Sie erkennen, ob Sie ein Verzeichnis gefunden haben, und überspringt den Foreach-Object, da Sie die Eigenschaft einfach direkt ziehen und alles in die Datei sichern können.

$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

Ich weiß, das ist ziemlich alt - aber auf der Suche nach einer einfachen Lösung bin ich über diesen Thread gestolpert ... Wenn ich die Frage richtig gestellt habe, suchten Sie nach einer Möglichkeit, mehrere Verzeichnisse mit Get-ChildItem aufzulisten. Mit Powershell 5.0 scheint es viel einfacher zu sein - zum Beispiel

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

Ohne die Klausel -Exclude wären tmp und music immer noch in dieser Liste. Wenn Sie -Name nicht verwenden, funktioniert die Klausel -Exclude aufgrund der detaillierten Ausgabe von Get-ChildItem .. nicht. Diese Option hilft einigen Benutzern, die nach einer einfachen Möglichkeit suchen, alle Verzeichnisnamen ohne bestimmte Namen aufzulisten ...

Prost Lil

4
lil

VertigoRay erklärte in seiner Antwort, dass -Exclude nur auf der Blattebene eines Pfads funktioniert (für eine Datei der Dateiname mit entferntem Pfad; für ein Unterverzeichnis der Verzeichnisname mit entferntem Pfad). Es sieht also so aus, als könne -Exclude nicht dazu verwendet werden, ein Verzeichnis anzugeben (z. B. "bin") und alle Dateien und Unterverzeichnisse in diesem Verzeichnis auszuschließen.

Hier ist eine Funktion, um Dateien und Unterverzeichnisse eines oder mehrerer Verzeichnisse auszuschließen (ich weiß, dass die Frage nicht direkt beantwortet wird, aber ich dachte, es könnte nützlich sein, um die Einschränkungen von -Exclude zu umgehen): 

$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

Für einen Verzeichnisbaum:

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

Das Ergebnis ist:

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

Es schließt den bin\-Unterordner und seinen gesamten Inhalt aus, schließt jedoch die Dateien Bin.txt oder bin (Datei mit dem Namen "bin" ohne Erweiterung) nicht aus.

1
Simon Tewsi

Sie können das Regex-Symbol oder das Regex-Symbol wie folgt ausschließen, vorausgesetzt, eine gewünschte Datei hat nicht denselben Namen wie ein Ordner, den Sie ausschließen.

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

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

in Ihrem Fall könnten Sie dies mit folgendem erreichen:

    mv excluded_dir ..\
    ls -R 
    mv ..\excluded_dir .
0
udito