Powershell Challenge

7

Друг попросил меня сделать следующее:

«Найдите самый быстрый и простой способ сортировки списка каталогов по последнему символу имен файлов».

Он сделал это в Linux, используя следующее:

ls | rev | sort | rev 

Я хотел бы показать ему альтернативу powershell, но я только начинаю изучать powershell и не могу этого сделать. Итак, я обманываю и прошу вашей помощи.

Ричард
источник
1
На самом деле это сортирует его не только по последнему символу, но и по всем последующим символам. Ответ Сэма Когана ниже строго последним и игнорирует любые последующие символы.
Сим
Прежде чем кто-либо проголосует за повторную
raven
Я думаю, что эта проблема вводит в заблуждение, и, кроме того, это несправедливое сравнение Linux с PowerShell. Если бы rev был сортировать только последний символ, это было бы справедливо. Также, что может быть более справедливым, так это попросить людей написать bash или что-то еще, чтобы отсортировать только последний символ, а не просто сделать: «ls | rev | sort | ls». Но, честно говоря, зачем кому-то нужна эта странная функция? Я все еще ломаю голову, разве что пытаюсь убедить кого-то, что PowerShell может быть таким же компактным, как sh, но со сравнением яблок и апельсинов?
эллиптический вид

Ответы:

3

К сожалению, в Powershell нет простого простого обратного метода, поэтому вместо этого вам нужно получить последнюю букву строки и отсортировать по ней. Это один из способов, которым я это сделал:

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

Как уже указывалось, это будет сортировать строго по последней букве, тогда как я версия Linux будет сортировать по последним и последующим буквам, так что может быть лучший способ сделать это, или вам, возможно, придется ввести некоторые циклы если ты так хочешь.

Сэм Коган
источник
Это Брилл. Не такой короткий, как альтернатива Linux, но все же довольно хороший.
Ричард
Я также заметил, что это сортирует только по последней букве, в отличие от версии для Linux. Однако задача, заявленная «последним персонажем», поэтому этот ответ отвечает на вопрос, даже если два решения не равны.
Ричард
Из-за некоторой путаницы этот вопрос был перенесен в переполнение стека, а затем не перенесен. Кит Хилл при переполнении стека добавил более короткий ответ ls | sort {"$ _" [- 1]}
Ричард
9

Вы можете попробовать это:

dir| sort {$_.name[-1]}
Шей Леви
источник
2
dir | sort -Property @{Expression ={$n = $_.Name.ToCharArray(); [Array]::Reverse($n);[String]::Join("",$n)}}

Не такая короткая, как версия для Unix, в основном потому, что в .NET Framework нет функции String.Reverse (). В основном это работает, говоря sort «сортировать путем вычисления этого выражения на входных аргументах».


Теперь, если какая-либо оболочка Unix работает лучше, чем

dir | sort -Property Length -Descending

чтобы сначала распечатать все файлы с самым большим, мне было бы интересно его увидеть.

user25572
источник
4
Как насчет 'ls -S'?
Брайан
Вот Это Да! Не знал об этом: D Хороший :)
AntonioCS
2

Я уверен, что кто-то может сделать это лучше, но вот один способ, который полностью совместим с lynix. Его преимущество заключается в том, что вы можете использовать многоразовую revстроковую функцию для вашего набора инструментов, то есть сортировать всю строку, а не только последний символ:

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

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

Я думаю, что foreach здесь хорошо демонстрирует, как каналы PowerShell являются массивами, а не просто строками, как в * nix.

Мне потребовалось немного времени, чтобы понять, что я должен использовать только, $_а не $_.nameвнутри 2-го foreach. Итак, я узнал кое-что о вариациях содержимого массива от одного канала к другому.

* Кредит на смелость моей функции rev идет на http://rosettacode.org/wiki/Reverse_a_string#PowerShell


Работает как Lynix:

  • реж | sort -Property @ {Expression = {$ n = $ _. Name.ToCharArray (); [Массив] :: Reverse ($ п) [String] :: Join ( "", $ п)}}

Вроде работает как lynix, но очень-очень медленно:

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

Не работают как lynix, т.е. не сортируют все символы имен файлов; (сортирует только самый последний символ строки):

  • реж | sort {$ .name.Substring ($ .name.length-1)}
  • реж | sort {$ _. name [-1]}
  • Ls | сортировать {. $ _ Name [-1]}
  • Ls | сортировать { "$ _" [- 1]}
  • ls -n | sort {$ _ [- 1]}
Эллиптический вид
источник
Это может быть улучшено, если функция rev принимает массив. Затем вы можете исключить forEach в коде, как будет вызывать функция. Вы можете добавить пару вещей, чтобы сделать ls | rev | sort | revполностью действительным самостоятельно. :-)
Кори Кнутсон,
1

Вариант Шей намного короче принятого ответа путем индексации в строке, но даже это можно улучшить. Вы можете сократить его еще больше, исключив ненужные пробелы и используя более короткий псевдоним:

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

Также вы можете использовать (сокращенно) -Nameаргумент для Get-ChildItem:

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

который будет возвращать строки напрямую.

Если вы действительно хотите отсортировать по обратной строке, то работает следующее (но медленно):

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

Вы можете сделать это быстрее, если у вас есть верхняя граница длины имени файла.

детеныш
источник
Цитирую вопрос: »Найдите самый быстрый и простой способ сортировки списка каталогов по последнему символу имен файлов.«. Это просто нужно отсортировать по последнему символу. Если самый простой способ сделать это - перевернуть строку, пусть будет так, но если самый простой способ сделать это - просто отсортировать по последнему символу, то это также решает задачу. Вопрос не был в том, «Как я могу сделать этот фрагмент оболочки Unix точно таким же в PowerShell?».
Джои
Сожалею. Я неправильно понял.
эллиптический вид