Von Powershell ls -R *.txt
werden Dateien rekursiv nach Verzeichnis aufgelistet, oder noch besser:
PS> Get-ChildItem -Path C:\Test -Name
Protokolle
anotherfile.txt
Command.txt
CreateTestFile.ps1
ReadOnlyFile.txt
aber wie füttere ich das in ein Array? Ich möchte ein Array des Dateiobjekts (?) selbst, das Folgendes betrachtet:
Get-ChildItem "C:\WINDOWS\System32" *.txt -Recurse | Select-Object FullName
https://stackoverflow.com/a/24468733/262852
Ich suche nach einem Array von "Datei" -Objekten mit Powershell aus diesen Befehlstypen.
wahrscheinlich bessere Syntax:
Copy-Item -Filter *.txt -Path c:\data -Recurse -Destination C:\temp\text
aber anstatt die Elemente zu kopieren, möchte ich nur ein Objekt oder besser gesagt ein Array von Objekten. Nicht der Pfad zu einer Datei, nicht die Datei, aber vermutlich eine Powershell-Referenz oder ein Zeiger auf eine Datei.
(Lesen Sie jetzt das schöne Handbuch.)
Lösung des Problems
tl; Dr
$output = Get-ChildItem...
Wenn Sie die Ausgabe einer PowerShell-Anweisung in einer Variablen (z. B. ) erfassen, wird sie automatisch in einem Array erfasst, wenn zwei oder mehr Ausgabeobjekte vorhanden sind.Um sicherzustellen, dass immer ein Array verwendet wird - auch mit nur einem einzigen oder keinem Ausgabeobjekt - verwenden Sie
@(...)
(z. B.$output = @(Get-ChildItem...)
)
PowerShell-Cmdlets wie
Get-ChildItem
, können eine beliebige Anzahl von Objekten ausgeben.Get-ChildItem
Ausgaben[System.IO.FileInfo]
und/oder[System.IO.DirectoryInfo]
Objekte, je nachdem, ob Informationen über Dateien und/oder Verzeichnisse ausgegeben werden.So bestimmen Sie die Ausgabeobjekttypen eines bestimmten Cmdlets:
- Laufen, z.
(Get-Command Get-ChildItem).OutputType
- Wenn das nicht funktioniert oder um zu sehen, welche Typen für einen bestimmten Aufruf ausgegeben werden, verwenden Sie
Get-ChildItem | Get-Member
. Get-Help -Full Get-ChildItem
sollteOUTPUTS
ebenso wie die Online-Hilfe einen Abschnitt anzeigen, allerdings nicht, dass es in diesem FallGet-ChildItem
weniger spezifisch wäre, daGet-ChildItem
es auch mit anderen Anbietern als dem Dateisystem funktioniert.
- Laufen, z.
Bei der Ausgabe an die Pipeline wird jedes Ausgabeobjekt einzeln an den nächsten Befehl in der Pipeline zur typischerweise sofortigen Verarbeitung übergeben.
Wenn die Ausgabe in einer Variablen (
$var =...
) erfasst wird, gilt die folgende Logik:- Wenn zwei oder mehr Objekte ausgegeben werden, werden sie in einem regulären PowerShell-Array gesammelt, das vom Typ ist
[object[]]
(obwohl die eigentlichen Elemente bestimmte Typen haben). - Wenn ein Objekt ausgegeben wird, wird es unverändert ausgegeben; das heißt, es ist nicht in ein Array eingeschlossen.
- Wenn keine Objekte ausgegeben werden, wird ein "array-valued null" ausgegeben (manchmal wegen seines Typnamens "AutomationNull" genannt), das sich in Ausdruckskontexten wie
$null
und in Enumerationskontexten wie eine leere Auflistung verhält; es führt zu keiner sichtbaren Ausgabe - siehe diese Antwort für Details.
- Wenn zwei oder mehr Objekte ausgegeben werden, werden sie in einem regulären PowerShell-Array gesammelt, das vom Typ ist
Daher kann ein bestimmter Befehl, wenn er in einer Variablen erfasst wird, situationsbedingt Folgendes zurückgeben:
- eine Reihe von Objekten
- ein einzelnes Objekt
- "nichts" (
[System.Management.Automation.Internal.AutomationNull]::Value
)
Um sicherzustellen, dass die Ausgabe eines bestimmten Befehls immer als Array behandelt wird, haben Sie zwei Möglichkeiten:
Verwenden Sie
@(...)
, den Array-Unterausdrucksoperator; z.B$fileSystemObjects = @(Get-ChildItem -Recurse -Filter *.txt)
Beschränken Sie die Zielvariable mit
[array]
(was äquivalent und einfacher einzugeben ist als[object[]]
).[array] $fileSystemObjects = Get-ChildItem -Recurse -Filter *.txt
Allerdings müssen Sie sich in PSv3 + oft keine Gedanken darüber machen, ob eine bestimmte Variable einen Skalar (Einzelwert) oder ein Array enthält, da Skalare implizit wie Arrays behandelt werden können: Sie können sogar Skalare aufrufen .Count
und die Indizierung ( [0]
, [-1]
) verwenden - siehe diese Antwort für Details.
Keine Kommentare:
Kommentar veröffentlichen