Desafio Powershell

7

Fui desafiado por um amigo a fazer o seguinte:

"Encontre a maneira mais rápida e fácil de classificar uma lista de diretórios pelo último caractere dos nomes de arquivos."

Ele fez isso no Linux usando o seguinte:

ls | rev | sort | rev 

Eu gostaria de mostrar a ele a alternativa do PowerShell, mas estou apenas começando a aprender PowerShell e não posso fazê-lo. Então, estou trapaceando e pedindo sua ajuda.

Richard
fonte
11
Na verdade, isso está classificando-o não apenas pelo último caractere, mas por todos os caracteres a seguir. A resposta de Sam Cogan abaixo é estritamente pelo último caractere e ignora os seguintes caracteres.
Sim
Antes que alguém votos para migrar esta pergunta novamente, ter um olhar para isto: meta.stackexchange.com/questions/32471/...
corvo
Eu acho que esse desafio é enganoso e, além disso, não é uma comparação justa do linux com o PowerShell. Se rev fosse apenas para classificar o último caractere, seria justo. Além disso, o que seria mais justo seria também pedir às pessoas que escrevessem bash ou qualquer outra coisa para classificar apenas o último caractere, e não simplesmente: "ls | rev | sort | ls". Mas, honestamente, por que alguém iria querer essa função estranha, eu ainda estou coçando a cabeça, exceto, talvez, para tentar convencer alguém de que o PowerShell pode ser tão compacto quanto sh, mas com uma comparação de maçãs com laranjas?
Visualização elíptica

Respostas:

3

Infelizmente, o Powershell não possui um método reverso fácil e agradável; portanto, você deve obter a última letra da string e classificá-la. Esta é uma maneira que eu fiz:

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

Como foi apontado, isso será estritamente classificado apenas pela última letra, enquanto que a versão Linux classificará pela última e depois pelas letras subsequentes, portanto, pode haver uma maneira melhor de fazer isso, ou talvez seja necessário introduzir algumas repetições. se você quiser assim.

Sam Cogan
fonte
Isso é maravilhoso. Não é tão curto quanto a alternativa do Linux, mas ainda é muito bom.
Richard
Notei também que isso só é classificado pela última letra, ao contrário da versão linux. No entanto, o desafio declarado "pelo último personagem", portanto, esta resposta responde à pergunta, mesmo que as duas soluções não sejam iguais.
Richard
Devido a alguma confusão, essa pergunta foi migrada para o Stack Overflow e, em seguida, não migrada. Keith Hill em estouro de pilha aditados os ls resposta mais curtos | tipo { "$ _" [- 1]}
Richard
9

Você pode tentar isso:

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

Não é tão curto quanto a versão unix, principalmente porque não há uma função String.Reverse () no .NET Framework. Basicamente, isso funciona dizendo ao tipo 'classificar computando esta expressão nos argumentos de entrada'.


Agora, se qualquer shell unix se sair melhor que

dir | sort -Property Length -Descending

para imprimir todos os arquivos com o maior primeiro, eu estaria interessado em vê-lo.

user25572
fonte
4
Que tal 'ls -S'?
5119 Bryan
Uau! Não sabia sobre esse: D Nice one :) #
AntonioCS /
2

Tenho certeza que alguém pode fazer isso melhor, mas aqui está uma maneira de ser totalmente compatível com o lynix. Ele tem o benefício de deixá-lo com uma revfunção de string reutilizável para sua caixa de ferramentas, ou seja, classifica a string inteira e não apenas o último caractere:

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

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

Acho que o foreach aqui demonstra bem como os tubos do PowerShell são matrizes e não simplesmente cadeias de caracteres como no * nix.

Demorei um pouco para perceber que eu tinha que usar apenas $_e não $_.namedentro do 2º foreach. Então, eu aprendi algo sobre variações no conteúdo da matriz de um canal para o outro.

* O crédito pelas tripas da minha função rev vai para http://rosettacode.org/wiki/Reverse_a_string#PowerShell


Funciona como lynix:

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

Funciona como o lynix, mas muito, muito lento:

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

Não funcione como o lynix, ou seja , falhe ao classificar todos os caracteres dos nomes dos arquivos; (classifica apenas o último caractere da string):

  • dir | classificar {$ .name.Substring ($ .name.length-1)}
  • dir | classifique {$ _. name [-1]}
  • ls | sort {$ _. Nome [-1]}
  • ls | classificar {"$ _" [- 1]}
  • ls -n | sort {$ _ [- 1]}
Vista elíptica
fonte
Isso pode ser melhorado, fazendo com que a função rev aceite uma matriz. Em seguida, você pode eliminar o forEach no código, como a função o chamaria. Você pode adicionar algumas coisas para tornar o ls | rev | sort | revcompletamente válido por conta própria. :-)
Cory Knutson
1

A variante de Shay é bem menor que a resposta aceita indexando a string, mas mesmo isso pode ser melhorado. Você pode reduzi-lo ainda mais excluindo espaços desnecessários e usando um alias mais curto:

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

Além disso, você pode usar o -Nameargumento (abreviado) para Get-ChildItem:

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

que retornará as strings diretamente.

Se você realmente deseja classificar pela string reversa , o seguinte funciona (mas é lento):

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

Você pode torná-lo mais rápido se tiver um limite superior no comprimento do nome do arquivo.

Joey
fonte
Citando a pergunta: »Encontre a maneira mais rápida e fácil de classificar uma listagem de diretório pelo ÚLTIMO caractere dos nomes de arquivo.«. Ele só precisa classificar pelo último caractere. Se a maneira mais fácil de fazer isso é reverter a cadeia, seja assim, mas se a maneira mais fácil de fazer isso é apenas classificando pelo último caractere, isso também resolve a tarefa. A pergunta não era sobre »Como posso fazer esse trecho de shell do Unix exatamente da mesma forma no PowerShell?«.
Joey
Desculpa. Eu entendi errado.
Visualização elíptica
-1
ls|sort{"$_"[-1]}
juan
fonte