Powershell größer als x und kleiner als y

senoyches

Lt. Junior Grade
Registriert
Dez. 2018
Beiträge
475
Hallo zusammen,

wie dem Titel zu entnehmen ist klingt es ganz einfach, ist es aber irgendwie nicht, folgende Formel habe ich in Verwendung:

Für alle die es interessiert, das Script habe ich von einer Seite um mir Sachen wie Kameramodell und Höhe Breite etc. auszulesen.

Get-FileMetaData -folder (Get-childitem P:\Spiele\ -Recurse -Directory).FullName | ? {$_.hight -lt 1080}
Dieser Befehl geht ohne Probleme

Get-FileMetaData -folder (Get-childitem P:\Spiele\ -Recurse -Directory).FullName | ? {($.hight -gt 50) -and ($.hight -lt 1080)}
dieser hingegen geht nicht, ich habe es mit und ohne Klammern probiert, auch die Klammern um das gesamte Konstrukt, nicht will klappen, woran kann das liegen?

Gruß
Senoyches
 
Hinter dem $ fehlt _ ...
Also: $_.hight und nicht $.hight
 
Außerdem heißt es height
(zumindest im normalen Englisch und Programmcode, kenne mich mit Powershell und was das $_ Objekt da ist nicht aus)
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: GaborDenes
oha, stimmt, den Typo hab ich auch übersehen ...
Ergänzung ()

@pcBauer : Wenn du mit einem Get-Befehl etwas holst und weiter durch die Pipe schickst zum weiterfiltern, dann ist das Objekt aus dem Get-xxx immer im Objekt $_ (grob übersetzt kann man "current item" sagen).
Mit dem .xy dahinter kann man die Properties ansprechen wie eben height oder width (hier geht um Eigenschaften einer Bilddatei).
 
Zuletzt bearbeitet:
senoyches schrieb:
dieser hingegen geht nicht
Ist das Problem denn nun gelöst, oder nicht?
Die Sache mit dem $.hight ist nicht der einzige Fehler in dem zweiten Befehl. So müsste das aussehen, damit es funktioniert:

PowerShell:
Get-FileMetaData -Folder (Get-ChildItem "P:\Spiele\*" -Recurse -Directory).FullName | Where {$_.Hight -Gt 50 -And $_.Hight -Lt 1080}

Es wäre durchaus sinnvoll, wenn von einem Hilfesuchenden die entsprechende Rückmeldung kommen würde, denn dann hätten alle etwas davon.
 
d2boxSteve schrieb:
Hinter dem $ fehlt _ ...
Also: $_.hight und nicht $.hight

Also in diesem Fall scheint es anders zu sein, denn wie gesagt hight ging ja im ersten Befehl ohne Probleme, habe es aber mal probiert, es funktioniert sowohl hight als auch height

d2boxSteve schrieb:
oha, stimmt, den Typo hab ich auch übersehen ...
Ergänzung ()

@pcBauer : Wenn du mit einem Get-Befehl etwas holst und weiter durch die Pipe schickst zum weiterfiltern, dann ist das Objekt aus dem Get-xxx immer im Objekt $_ (grob übersetzt kann man "current item" sagen).
Mit dem .xy dahinter kann man die Properties ansprechen wie eben height oder width (hier geht um Eigenschaften einer Bilddatei).

Ja das war mir eigentlich bewusst, damals beim wilden rumprobieren konnte ich mir keine reim drauf machen, warum das eine geht das andere nicht, jetzt auf einmal einige Tage später sehe ich auch Anhieb mehrere Fehler, warum mir das damals nicht aufgefallen ist .... frag mich besser nicht, aber danke nochmal für die Erklärung.

Micha45 schrieb:
Ist das Problem denn nun gelöst, oder nicht?
Die Sache mit dem $.hight ist nicht der einzige Fehler in dem zweiten Befehl. So müsste das aussehen, damit es funktioniert:

PowerShell:
Get-FileMetaData -Folder (Get-ChildItem "P:\Spiele\*" -Recurse -Directory).FullName | Where {$_.Hight -Gt 50 -And $_.Hight -Lt 1080}

Es wäre durchaus sinnvoll, wenn von einem Hilfesuchenden die entsprechende Rückmeldung kommen würde, denn dann hätten alle etwas davon.

Da stimme ich dir absolut zu, ich hasse es auch immer wenn ich etwas lese, weil ich auf der Suche nach einem Problem bin und nach zahlreichen Vorschlägen endet der Thread einfach, ich hab es schlicht und ergreifend aus den Augen verloren. Daher nun hier die Antwort:

Nein das Problem ist noch nicht gelöst, auch dein Vorschlag bringt keine Änderung.

Ich hielt in einem anderen Forum allerdings den Tipp, dass evtl. der Wert hight als string zurück gegeben wird und da ist 50 größer als 1080, somit käme niemals ein Ergebnis heraus, ich solle also mal schauen das vorher zu konverieren, damit kam ich aber noch nicht klar, denn ich habe dazu folgende Ansätze gefunden, allerdings laufen die genauso ins leere.

PowerShell:
Get-FileMetaData -folder (Get-childitem P:\Spiele\ -Recurse -Directory).FullName | ? {$_.height -gt [int]::Parse(50) -and $_.height -lt [int]::Parse(1080)}

und

PowerShell:
Get-FileMetaData -folder (Get-childitem P:\Spiele\ -Recurse -Directory).FullName | ? {$_.height -gt [convert]::ToInt32(50, 10) -and $_.height -lt [convert]::ToInt32(1080, 10)}

Hat einer zu letzterem Ansatz noch eine Idee?
 
Fangen wir doch mal vorne an, ich hab das versucht nachzustellen. Welche Funktion "Get-FileMetaData" hast du dir denn runtergeladen? Da gibt es mehrere auf z.B. "https://gallery.technet.microsoft.com/scriptcenter".

Wenn ich diese nehm: https://gallery.technet.microsoft.com/scriptcenter/get-file-meta-data-function-f9e8d804 , dann wird bei "Höhe" folgender String zurückgegeben:

1575963153357.png


Da steht "960 Pixel". Wenn ich jetzt folgende Zeile laufen lasse, bekomme ich alle Bilder mit diesem Wert:

Get-FileMetaData -folder (Get-childitem D:\download\bilder\ ).FullName | ? {($_.Höhe -eq "960 Pixel")}

Diesen String kannst du aber so nicht als Zahl vergleichen oder sofort konvertieren, du müsstest ihn vorher am Leerzeichen splitten und nur das erste Element benutzen. Das kann dann in eine Zahl konvertiert werden und danach verglichen.
Beachte auch, ich vergleiche nicht "Hight" sondern "Höhe". Das hängt leider auch von der Sprachversion deiner Powershell ab.
Was bei dir zurückkommt kannst du mit testen, in dem du den Filter hinten erstmal weglässt. Bei mir sieht das so aus:

1575963956809.png
 
d2boxSteve schrieb:
Fangen wir doch mal vorne an, ich hab das versucht nachzustellen. Welche Funktion "Get-FileMetaData" hast du dir denn runtergeladen? Da gibt es mehrere auf z.B. "https://gallery.technet.microsoft.com/scriptcenter".

Wenn ich diese nehm: https://gallery.technet.microsoft.com/scriptcenter/get-file-meta-data-function-f9e8d804 , dann wird bei "Höhe" folgender String zurückgegeben:

Anhang anzeigen 851492

Da steht "960 Pixel". Wenn ich jetzt folgende Zeile laufen lasse, bekomme ich alle Bilder mit diesem Wert:

Get-FileMetaData -folder (Get-childitem D:\download\bilder\ ).FullName | ? {($_.Höhe -eq "960 Pixel")}

Diesen String kannst du aber so nicht als Zahl vergleichen oder sofort konvertieren, du müsstest ihn vorher am Leerzeichen splitten und nur das erste Element benutzen. Das kann dann in eine Zahl konvertiert werden und danach verglichen.
Beachte auch, ich vergleiche nicht "Hight" sondern "Höhe". Das hängt leider auch von der Sprachversion deiner Powershell ab.
Was bei dir zurückkommt kannst du mit testen, in dem du den Filter hinten erstmal weglässt. Bei mir sieht das so aus:

Anhang anzeigen 851498

Korrekt du hast genau das richtige Script genommen.

Ja, ich habe bei mir auch höhe stehen wenn ich die auflisten. Lasse komischerweise funktioniert des aber eben auch mit Hight und height, evtl. ist die Powershell ja merkwürdig installiert denn die meisten Hilfetexte habe ich auch in englisch, habe die aber eben auch noch nicht geupdatet.

Aber danke für den Tipp mit dem Pixel dahinter da hätte ich mich totkonvertieren können, hier wäre ggf. eine Fehlermeldung schön gewesen das dies in den Typ int nicht möglich ist. Dann wäre ich bestimmt selbst irgendwann drauf gekommen.

Jetzt wäre aber die entscheidende Frage, wie sage ich der Powershell schneide vor dem ersten Leerzeichen ab, meine mal was mit splitstring oder so gesehen zu haben. Denn ich denke mal weiter. Ein billiger Screenshot aus alten Zeiten kann auch mal gerne eine Auflösung wie 96x72 ein HD Ready Bild mit 1280 x 720 wäre da 3 stellig, Full HD 1920 x 1080 vierstelligen und Bilder von modernen Highend Kameras greifen die 5 stellen an.

Wenn du da einen Ansatz hast würde ich mich gerne versuchen da reinzudenken.

Mir käme jetzt als erste Idee:
Wenn 3 Stelle kein Leerzeichen, dann prüfe 4 Stelle usw.

Genau da stoße ich vermutlich aber auf das nächste Problem. Wie ziehe ich das aus dem Objekt raus bzw. wie übergebe ich es an die Suche. So das ich einen Vergleich bzw. eine "Bereichsfilter" machen kann.

Sicher hast du bereits gemerkt ich bin da noch nicht so erfahren, aber an solchen Problemen versuche ich zu wachsen. Nur oftmals sind die Tipps die "Profis" bringen so formuliert das der Einsteiger wenig davon versteht.

Grüße
Senoyches

- mobil gesendet
 
Das geht so, habs eben getestet:

Get-FileMetaData -folder (Get-childitem D:\download\bilder\ ).FullName | ? {($.Höhe.Split(' ')[0] -gt 950) -and ($.Höhe.Split(' ')[0] -lt 970)}

Split(' ') trennt am Leerzeichen und [0] nimmt das erste Element aus dem Ergebnis, eben die Zahl. Die brauchst du nichtmal konvertieren.

Du musst halt deinen Pfad und deine Pixeleinschränkungen verwenden.
Das Gleiche geht dann auch bei Breite.
Ergänzung ()

Ich merke gerade, bei dem "Dollarzeichen" fehlt danach der Unterstrich, das kam durch paste+copy hier rein. Der Unterstrich muss nach dem "Dollarzeichen" noch rein.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: senoyches
Teste das gleich mal zu Hause und vielen Dank für die Erklärung ich glaube die Split Funktion werde ich noch oft benötigen.

d2boxSteve schrieb:
Ich merke gerade, bei dem "Dollarzeichen" fehlt danach der Unterstrich, das kam durch paste+copy hier rein. Der Unterstrich muss nach dem "Dollarzeichen" noch rein.

Okay, dann war es vielleicht bei mir bei meinem allerersten Beitrag auch so denn in einem anderen Forum habe ich exakt den gleichen Code ei gefügt und da war der Unterstrich mit drin, mal in Zukunft drauf achten.
 
Wenn feststeht, dass dort immer " Pixel" steht, könnte man auch statt "Split"
$_.Höhe.Replace(" Pixel", "") nehmen.
Damit putzt man immer das Leerzeichen vor dem Wort "Pixel" und das Wort selbst weg und man bräuchte somit nicht auf die Anzahl der Stellen bei den Werten achten.

Eine ForEach-Schleife einzubauen, wäre vielleicht auch noch sinnvoll.

d2boxSteve schrieb:
? {($.Höhe.Split(' ')[0] -gt 950) -and ($.Höhe.Split(' ')[0] -lt 970)}
Nur eine Verständnisfrage: Warum die beiden ( ) ? Die sind unnötig an der Stelle. Führt aber auch nicht zu einer Fehlermeldung.

Aus praktischer Erfahrung weiß ich, dass das Verwenden von Kurznamen oder Zeichen ("alias") nicht selten zu Fehlern oder Fehlausgaben führt.
Deshalb lieber z.B. "Where-Object", statt "Where" oder "?", oder "ForEach-Object", statt "ForEach" oder "%" usw.
 
Zuletzt bearbeitet von einem Moderator:
  • Gefällt mir
Reaktionen: senoyches
Die beiden Klammern sind optional um erkennbar zu machen, dass diese Bedingung zusammengehört. In anderen Sprachen ist die Pflicht.
Ergänzung ()

Und @TE: ja, das war denke ich das Problem mit den fehlenden Unterstrichen.
 
  • Gefällt mir
Reaktionen: Micha45
Zurück
Oben