Powershell größer als x und kleiner als y

senoyches

Ensign
Dabei seit
Dez. 2018
Beiträge
183
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
 

d2boxSteve

Captain
Dabei seit
Apr. 2010
Beiträge
3.331
Hinter dem $ fehlt _ ...
Also: $_.hight und nicht $.hight
 

pcBauer

Lieutenant
Dabei seit
Feb. 2007
Beiträge
914
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:

d2boxSteve

Captain
Dabei seit
Apr. 2010
Beiträge
3.331
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:

Micha45

Commander
Dabei seit
Mai 2009
Beiträge
2.296
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.
 

senoyches

Ensign
Ersteller dieses Themas
Dabei seit
Dez. 2018
Beiträge
183
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

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.

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?
 

d2boxSteve

Captain
Dabei seit
Apr. 2010
Beiträge
3.331
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
 

senoyches

Ensign
Ersteller dieses Themas
Dabei seit
Dez. 2018
Beiträge
183
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 851492 betrachten

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 851498 betrachten
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
 

d2boxSteve

Captain
Dabei seit
Apr. 2010
Beiträge
3.331
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:

senoyches

Ensign
Ersteller dieses Themas
Dabei seit
Dez. 2018
Beiträge
183
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.

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.
 

Micha45

Commander
Dabei seit
Mai 2009
Beiträge
2.296
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.

? {($.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:

d2boxSteve

Captain
Dabei seit
Apr. 2010
Beiträge
3.331
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.
 
Top