web-dev-qa-db-fra.com

Comment puis-je exclure plusieurs dossiers à l'aide de Get-ChildItem -exclude?

J'ai besoin de générer un fichier de configuration pour notre système Pro/Engineer CAD. J'ai besoin d'une liste récursive des dossiers d'un lecteur particulier sur notre serveur. Cependant, je dois EXCLURE tout dossier contenant 'ARCHIVE', y compris les différents cas.

J'ai écrit ce qui suit qui fonctionne sauf qu'il n'exclut pas les dossiers !! 

$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

Je le ferais comme ça:

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

Mon approche KISS pour ignorer certains dossiers enchaîne les appels Get-ChildItem. Cela exclut les dossiers de niveau racine mais pas les dossiers de niveau plus profond si c'est ce que vous voulez.

Get-ChildItem -Exclude folder1,folder2 | Get-ChildItem -Recurse | ...
  • Démarrer exclure les dossiers que vous ne voulez pas 
  • Ensuite, faites la recherche récursive avec les dossiers non souhaités exclus.

Ce qui me plaît dans cette approche, c’est que c’est simple et facile à retenir. Si vous ne voulez pas mélanger des dossiers et des fichiers lors de la première recherche, un filtre sera nécessaire.

17
guillem

Le modèle d'exclusion devrait ne respecte pas la casse, vous ne devriez donc pas avoir à spécifier tous les cas pour l'exclusion.

Cela dit, le paramètre -Exclude accepte un tableau de chaînes. Par conséquent, tant que vous définissez $archive en tant que tel, vous devez être défini.

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

Vous devez également supprimer l'astérisque de fin de $folder - puisque vous spécifiez -recurse, il vous suffira de donner le dossier de niveau supérieur.

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

Script entièrement révisé. Cela modifie également la façon dont vous détectez si vous avez trouvé un répertoire et ignore le Foreach-Object parce que vous pouvez simplement extraire la propriété directement et la sauvegarder dans le fichier.

$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

Je sais que c'est assez ancien - mais à la recherche d'une solution facile, je suis tombé sur ce fil de discussion ....... Si j'ai bien compris la question, vous cherchiez un moyen de répertorier plusieurs répertoires à l'aide de Get-ChildItem. Il semble y avoir un moyen beaucoup plus facile d’utiliser Powershell 5.0 - exemple

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

Sans la clause -Exclude, tmp et musique seraient toujours dans cette liste. Si vous n'utilisez pas -Name, la clause -Exclude ne fonctionnera pas, en raison de la sortie détaillée de Get-ChildItem . Nous espérons que cela aidera certaines personnes à la recherche d'un moyen simple de répertorier tous les noms de répertoires sans certains. ...

À la vôtre Lil

4
lil

VertigoRay, dans sa réponse, a expliqué que -Exclude ne fonctionne qu'au niveau feuille d'un chemin (pour un fichier, le nom du fichier avec chemin supprimé, pour un sous-répertoire, le nom du répertoire avec chemin supprimé). Il semble donc que -Exclude ne peut pas être utilisé pour spécifier un répertoire (par exemple, "bin") et exclure tous les fichiers et sous-répertoires de ce répertoire.

Voici une fonction pour exclure les fichiers et les sous-répertoires d'un ou de plusieurs répertoires (je sais que cela ne répond pas directement à la question, mais j'ai pensé que cela pourrait être utile pour contourner les limitations de -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

Pour une arborescence de répertoires:

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

Le résultat est:

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

Il exclut le sous-dossier bin\et tout son contenu, mais non les fichiers Bin.txt ou bin (fichier nommé "bin" sans extension).

1
Simon Tewsi

Vous pouvez exclure comme ceci le symbole regex 'ou', en supposant qu'un fichier que vous voulez n'a pas le même nom qu'un dossier que vous excluez.

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

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

peut être dans votre cas, vous pouvez atteindre ceci avec ce qui suit:

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