Powershell - Wieso fehtl ein Stück vom String?

3 Antworten

Nö da fehlt kein Stück vom String...

Da du auch Ordner ermittelst hängt da natürlich kein Dateiname dran...

Dies schließt Du aus, indem du mit dem Parameter -File nur Dateien suchst.

Das nächste Problem ist, das Du an $file lediglich eine Liste von fullnames übergibst und somit garnicht auf die Dateizeiten zugreifen kannst.

Die Macht von Powershell liegt in der Pipe...

$source = 'x:\Ordner der  dursucht wird'
$filter = "*.extension"
$DelTime = -1
  # lass Get_ChildItem  alles  wozu es fähig ist selbst tun, dazu gehört auch das Filtern auf wildcerds für Dateinamen  (das  retutiert schonmal  den Input für die Pipeline)
  #jage die komletten Fileobjekte  in die Pipeline  ($_ ist  immer  das aktuell übergebene Objekt)
$FileNames_list=@(Get-ChildItem -Path $source -Filter $filter -Recurse -File -ErrorAction silent |  
    Where-Object {$_.LastAccessTime -le (get-date).AddMinutes($DelTime)} | #jetz  brauchst   du  nur noch  filtern was gci nicht kann
    ForEach-Object -Begin {$i = 0} -Process {  #hier  kommen  nur noch die Objekte an, welche welche durch alle Filter  gerutscht sind
        Write-Host "Datei-Nr.: $i heißt: $($_.FullName)" -fo green  #Writehost ist gut zum Beobachten, da es immer auf den Bildschirm schreibt aber nicht in die Pipe
        $i++

        $_.FullName                                              #wird in die Pipe geschrieben 
    }                                                            # ...und da kein weiterer Pipefilter folgt ins Array, welches an die Zielvariable  übergeben  wird
)
$FileNames_list[0]
'alle anzeigen
'
$FileNames_list
pause

der Vorteil dieses vorgehens ist : Du Quälst die Speicherverwaltung nicht mit mit Erweitern von Arrays , die Pipe ist immer schneller als ein foreach-loop welcher mit globalen Variablen herumzirkelt.

obiges war "Schönschrift" mit übertriebener Kommentierung

Das geht natürlich auch schluderig:

$FileNames_list=@( dir $source -Filter $filter -Recurse -File -EA silent | ?{$_.LastAccessTime -le (get-date).AddMinutes($DelTime)} |%{ $_.FullName } )
$FileNames_list
pause
Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren

DNSxxx 
Beitragsersteller
 07.05.2022, 22:10

Hallo Wiedermal.

Erstmal vielen Dank für deine Hilfe.

Hab zuerst ca. eine Stunde in Dr. Google gesetzt weil ich einen Kommentar von dir überlesen habe. (Obwohl du es eh so schön geschrieben hattest)

Hab zuerst nicht raus gefunden wieso meine Liste danach immer leer war.

Das hatte ich überlesen:

#wird in die Pipe geschrieben 
    }                                                            # ...und da kein weiterer Pipefilter folgt ins Array, welches an die Zielvariable  übergeben  wird
0
Erzesel  08.05.2022, 09:11
@DNSxxx

Wenn Du mit Foreach-Object operierst, musst Du das dort ermittelte Ergebnis auch der Pipe übergeben.

1..10| % {
  $_tempVar = $_*$_ #fuchtbaarkomlexe Formel
  #$_*$_  hätte in diesem Fall auch gereicht
  $_tempVar #Ergebnis der Pipe übergeben
}

Allerdings wäre es Unsinn für ein bloße Überprüfung jedes Elements (ohne Alternativzweig) % zu bemühen.

1..10| ?{ !($_ % 2) }

...prüft einfach ob das aktuelle Element ohne Rest durch 2 teilbar ist und in der Pipe verbleiben darf... . in einem solchen Fall musst Du nichts selbst in die Pipe schreiben. das ?{...} ist einfach nur ein Sieb, welches bestehendes Zeug durchlässt oder nicht.

1

Spätestens wenn du deinen Code richtig einrücken würdest, solltest du den Fehler sehen. Du fügst der Liste jeden Eintrag hinzu, über den iteriert wird. An Stelle 0 steht also erst einmal nur das Verzeichnis selbst.

Verschiebe

$file_list += $file

also in den if-Rumpf.


DNSxxx 
Beitragsersteller
 05.05.2022, 19:01

Hi. Danke für deine Antwort. Hab jetzt wirklich noch einen Moment gebraucht bis ich meinen ... Fehler gesehen hab.

Und du hast auch recht mit dem einrücken. Hab irgendwie noch keine Optimale Anordnung/Einrückung für mich gefunden wie ich meinen Code/Funktionen etc. Ordentlich lesbar mache.

0
regex9  05.05.2022, 19:12
@DNSxxx

In unserem Kulturkreis lesen wir von links nach rechts. Das Auge beginnt also stets am linken Rand. Daher eignen sich K&R- oder Allman-Style ganz gut.

k&r {
}

allman
{
}
1
DNSxxx 
Beitragsersteller
 05.05.2022, 19:52
@regex9

Solange immer nur eine Klammer ist , ist das klar. was ich meinte war wenn Klammern in Klammern ... verwendet werden.

Da hab ich jetzt schon ein paar verschiedene Arten zur Einteilung gesehen.

Ich habe vor ein paar Jahren Python versucht zu lernen (hab leider schon wieder viel vergessen).

Soweit ich mich erinnere hatte ich da eine bessere Struktur hinbekommen, bzw. ich glaub da war es teilweise sogar vorgeschrieben.

0
regex9  05.05.2022, 20:00
@DNSxxx

Dann würde ich den Code um einen Tab (bzw. 2/4/8 Leerzeichen) einrücken.

k {
  & {
    r {
    }
  }
}

So sind Blockanfang und -ende auf einer vertikalen Linie.

Bei Python kommt man ohne die geschweiften Klammern aus, allerdings sind die Einrückungen Zwang.

def do_something():
  value = 1

  if value == 1:
    print("Value is 1")
2
Erzesel  06.05.2022, 21:10
@regex9

Bei Powershell sind Einrückungen eigentlich nur Kosmetik.

Eine Pipeleine schreibt man gewöhnlich in einen Zeile . Ausgenommen Foreach-Objekt, dann rückt man den Rumpf ein.

$variable = Pipeinput | Filter | Filter | % {
    do Somethig
    output to Pipe
} | more filters ....

bei komplexeren Filtern:

$variable = Pipeinput |
  Filter |
  Filter |
  % {
      do Somethig
      output to Pipe
  } |
  more filters ....
0

Mal von der Einrückung abgesehen (auf die bin ich beim lesen der Frage selbst reingefallen): Ich würde dir empfehlen, nicht den Dateinamen auszulesen, sondern die Datei-Objekte selbst im Array zu speichern. Das ist meistens besser, wenn du damit weiter arbeiten willst.

Das "Get-Childitem" (ich kürze das immer ab mit "dir") hat auch noch einen Parameter -File, mit dem du sagen kannst, dass du nur Dateien und keine Ordner zurückkriegen willst. Und du kannst den Filter auch da direkt angeben.

Also z.B.

$source = 'E:\Powershell_Skripts\99 - Ordner für Tests\Source\MFU\'

// Alle *.dfq Dateien in dem Ordner suchen
$file_list = @(dir $source "*.dfq")

// Alle Dateien ausgeben, die vor mehr als einer Minute bearbeitet wurden
($file_list | where LastAccessTime -le (Get-Date).AddMinutes(-1)).FullName



DNSxxx 
Beitragsersteller
 06.05.2022, 17:30

Hallo.

Vielen Dank dafür, aber bei mir funktioniert das nicht.

Bei 

$file_list = @(dir $source)

bekomme ich (in meinem Fall) 3 Objekte in die Liste. Das sind aber nur Ordner und keine Dateien

Bei

$file_list = @(dir $source "*.dfq")

sind es 0 Objekte.

Da nichts in der Variable $file_list gespeichert wird kann ich nicht damit weitermachen. Oder ich mach was falsch.

0
DNSxxx 
Beitragsersteller
 06.05.2022, 18:54
@DNSxxx

Habs rausgefunden. Das -recurse fehlte. Und langsam kapier ich wie das mit dem Datei-Objekt funktioniert.

0