Powershell-Herausforderung

7

Ich wurde von einem Freund aufgefordert, Folgendes zu tun:

"Finden Sie den schnellsten und einfachsten Weg, eine Verzeichnisliste nach dem LETZTEN Zeichen der Dateinamen zu sortieren."

Er hat es unter Linux wie folgt gemacht:

ls | rev | sort | rev 

Ich würde ihm gerne die Powershell-Alternative zeigen, aber ich fange gerade erst an, Powershell zu lernen, und ich kann es nicht. Also betrüge ich und bitte um deine Hilfe.

Richard
quelle
1
Eigentlich sortiert es das nicht nur nach dem letzten Zeichen, sondern nach allen folgenden Zeichen. Die Antwort von Sam Cogan unten bezieht sich ausschließlich auf das letzte Zeichen und ignoriert alle folgenden Zeichen.
Sim
Bevor jemand abstimmt
Rabe
Ich denke, diese Herausforderung ist irreführend und außerdem kein fairer Vergleich von Linux mit PowerShell. Wenn rev nur das letzte Zeichen sortieren würde, wäre es fair. Fairer wäre es auch, die Leute zu bitten, Bash oder was auch immer zu schreiben, um nur das letzte Zeichen zu sortieren, und nicht einfach: "ls | rev | sort | ls". Aber ehrlich gesagt, warum sollte sich jemand diese seltsame Funktion wünschen? Ich kratzte mir immer noch am Kopf, außer vielleicht, um jemanden davon zu überzeugen, dass PowerShell so kompakt wie sh sein kann, aber mit einem Vergleich von Äpfeln mit Orangen?
Elliptische Ansicht

Antworten:

3

Leider hat Powershell keine schöne einfache Umkehrmethode. Stattdessen müssen Sie den letzten Buchstaben der Zeichenfolge abrufen und danach sortieren. Dies ist eine Möglichkeit, wie ich es getan habe:

dir| sort {$_.name.Substring($_.name.length-1)}

Wie bereits erwähnt, wird dies nur nach dem letzten Buchstaben sortiert, während in der Linux-Version nach dem letzten und den nachfolgenden Buchstaben sortiert wird. Daher gibt es möglicherweise eine bessere Möglichkeit, dies zu tun, oder Sie müssen möglicherweise eine Schleife einführen wenn du es so willst.

Sam Cogan
quelle
Das ist genial. Nicht so kurz wie die Linux-Alternative, aber trotzdem ziemlich gut.
Richard
Mir ist auch aufgefallen, dass dies im Gegensatz zur Linux-Version nur nach dem letzten Buchstaben sortiert ist. Die Herausforderung wird jedoch "durch das LETZTE Zeichen" angegeben, sodass diese Antwort die Frage beantwortet, auch wenn die beiden Lösungen nicht gleich sind.
Richard
Aufgrund einiger Verwirrung wurde diese Frage zu Stack Overflow migriert und dann nicht migriert. Keith Hill über Stapelüberlauf fügte die kürzere Antwort hinzu ls | sort {"$ _" [- 1]}
Richard
9

Sie können dies versuchen:

dir| sort {$_.name[-1]}
Shay Levy
quelle
2
dir | sort -Property @{Expression ={$n = $_.Name.ToCharArray(); [Array]::Reverse($n);[String]::Join("",$n)}}

Nicht so kurz wie die Unix-Version, hauptsächlich, weil es in .NET Framework keine String.Reverse () -Funktion gibt. Grundsätzlich funktioniert dies, indem sort "sort durch Berechnung dieses Ausdrucks für die Eingabeargumente" mitgeteilt wird.


Nun, wenn eine Unix-Shell besser als

dir | sort -Property Length -Descending

Um alle Dateien mit der größten zuerst zu drucken, wäre ich interessiert, sie zu sehen.

user25572
quelle
4
Wie wäre es mit 'ls -S'?
Bryan
Beeindruckend! Wusste nichts davon: D Schöne :)
AntonioCS
2

Ich bin sicher, dass jemand dies besser kann, aber hier ist eine Möglichkeit, die vollständig mit Lynix kompatibel ist. Es hat den Vorteil, dass Sie eine wiederverwendbare revZeichenfolgenfunktion für Ihre Toolbox haben, dh die gesamte Zeichenfolge und nicht nur das letzte Zeichen sortiert:

function rev ($s) {return -join ($s[$s.Length..0])}

dir | foreach{rev($_.name)} | sort | foreach{rev($_)}

Ich denke, die Foreachs hier zeigen gut, wie PowerShell-Pipes Arrays sind und nicht einfach Strings wie in * nix.

Es dauerte eine Weile, bis mir klar wurde, dass ich nur $_und nicht $_.nameinnerhalb des 2. verwenden musste foreach. Ich habe also etwas über Variationen im Array-Inhalt von einer Pipe zur nächsten gelernt.

* Gutschrift für den Mut meiner Rev-Funktion geht an http://rosettacode.org/wiki/Reverse_a_string#PowerShell


Funktioniert wie Lynix:

  • dir | sort -Property @ {Expression = {$ n = $ _. Name.ToCharArray (); [Array] :: Reverse ($ n); [String] :: Join ("", $ n)}}

Art von Arbeiten wie Lynix, aber sehr, sehr langsam:

  • ls -n | sort {$ _ [3e3..0]}

Arbeiten Sie nicht wie Lynix, dh sortieren Sie nicht alle Zeichen der Dateinamen. (sortiert nur das allerletzte Zeichen der Zeichenfolge):

  • dir | sort {$ .name.Substring ($ .name.length-1)}
  • dir | sortiere {$ _. name [-1]}
  • ls | sort {$ _. Name [-1]}
  • ls | sort {"$ _" [- 1]}
  • ls -n | sort {$ _ [- 1]}
Elliptische Ansicht
quelle
Dies könnte verbessert werden, indem die rev-Funktion ein Array akzeptiert. Dann könnten Sie forEach im Code entfernen, wie die Funktion es aufrufen würde. Sie können ein paar Dinge hinzufügen, um das ls | rev | sort | revvollständig für sich allein gültig zu machen . :-)
Cory Knutson
1

Shays Variante ist viel kürzer als die akzeptierte Antwort, indem sie in den String indiziert, aber selbst das kann verbessert werden. Sie können es noch weiter verkürzen, indem Sie unnötige Leerzeichen ausschließen und einen kürzeren Alias ​​verwenden:

ls|sort{$_.Name[-1]}

Sie können das (abgekürzte) -NameArgument auch verwenden, um Get-ChildItem:

ls -n|sort{$_[-1]}

Dies gibt Zeichenfolgen direkt zurück.

Wenn Sie wirklich nach der umgekehrten Zeichenfolge sortieren möchten, funktioniert Folgendes (ist aber langsam):

ls -n|sort{$_[3e3..0]}

Sie können es schneller machen, wenn Sie eine Obergrenze für die Länge des Dateinamens haben.

Joey
quelle
Zitat aus der Frage: »Finden Sie den schnellsten und einfachsten Weg, eine Verzeichnisliste nach dem LETZTEN Zeichen der Dateinamen zu sortieren.«. Es muss nur nach dem letzten Zeichen sortiert werden. Wenn der einfachste Weg, dies zu tun, das Umkehren der Zeichenfolge ist, sei es auch so. Wenn der einfachste Weg dies ist, nur nach dem letzten Zeichen zu sortieren, löst dies auch die Aufgabe. Die Frage lautete nicht »Wie kann ich diesen Ausschnitt der Unix-Shell in PowerShell genauso machen?«.
Joey
Es tut uns leid. Ich habe es falsch verstanden.
Elliptische Ansicht
-1
ls|sort{"$_"[-1]}
Juan
quelle