Ordenando qualquer coisa usando Windows Powershell

Olá,

conforme prometido, estou postando um truque interessante sobre o Powershell. Como vocês já devem ter visto, ele permite que criemos scripts de uma forma completamente diferente do normal, uma vez que ele é um shell que trabalha com objetos e não com texto, como todos os outros prompts de comando e shells. Isso dá toda a flexibilidade dele. O que eu vou mostrar agora é um exemplo disso.

Pense numa lista de arquivos. Isso pode ser obtido com o comando dir facilmente. Agora imagine ordenar esses arquivos por nome:

dir | sort-object 

Isso, por si só, já ordena os arquivos por nome. Agora, ordenando por data de criação.

dir | sort {$_.creationtime}

Perguntas comuns: Vinicius, o que significa o $_? É uma referência que você precisa usar dentro do bloque que o sort-object recebe para indicar o próprio arquivo. Imagine que o dir "pega" vários arquivos do disco, monta uma lista e manda pelo pipe para o próximo comando. O Sort pega os objetos novamente e busca, em cada um, a propriedade creationTime, que é a data de criação dele. Vinicius, e de onde você tirou esse creationTime? Iluminação divina? Não. Powershell mesmo. Você pode listar as propriedades de qualquer objeto no Powershell com o comando get-member ou simplesmente gm. Assim:

dir | get-member

É questão de fazer testes.

Agora o truque: e para não ordenar, ou seja, para embaralhar a lista?

PS > dir | sort {(new-object system.random (date).milliseconds).next()}


    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Documents and Settings\Vinicius Canto


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---          7/6/2007      2:15       4461 _vimrc
d----         26/6/2007     22:57            dwhelper
d-r--         24/6/2007     22:17            Desktop
d-r--         22/7/2006      8:38            Start Menu
-a---         12/6/2007     21:58        143 .rails-plugin-sources
d-r--         28/1/2005     15:04            Favorites
-a---          5/6/2007     13:45          0 The All-American Rejects - Move Along.mp3
-a---          1/7/2007     20:14      18033 _viminfo
-a---          5/6/2007     13:39          0 Outlook Express.lnk
d----         12/6/2007     14:09            Contacts
d---s          2/7/2007      1:44            Cookies

Pronto! O resultado seria esse que aparece logo abaixo do comando. E cada vez que você rodar o comando, vai ter uma lista diferente. No final das contas, não é 100% randômico por dois motivos: 1) Computadores não geram números aleatórios, mas sim pseudo-aleatórios. Isso acontece porque o computador não tem como chutar números e usa uma função matemática que nunca volta no mesmo número (e há provas disso). No entanto, isso não garante a aleatoriedade do número gerado. 2) Com o comando acima, eu sempre crio o objeto Random a cada vez que o comando é executado... isso significa que, com um pouco de sorte, você pode ter a mesma lista se acertar o número de milissegundos. O certo, nesse caso, seria criar o objeto uma linha antes e só chamar o método Next() sempre que precisar do número. Mas para embaralhar uma lista dessas uma única vez, serve.

Ah, um detalhe: isso serve para qualquer lista de objetos no Powershell. Isso inclui lista de nomes, arquivos texto, lista de mailboxes do Exchange, usuários do AD, e aí vai... as possibilidades são infinitas. Veja o exemplo que motivou esse post. Precisei embaralhar o conteúdo de um arquivo texto:

${c:\arquivo.txt} = ${c:\arquivo.txt} | sort {(new object system.random).next()}

 A próxima postagem continua sobre Powershell, mas sobre aliases. Até mais!

Categorias dessa postagem:

Comentários

Anônimo : Grande Vinicius,

muito legal este exemplo. Ele prova que já é hora de começar a estudar Power Shell. Eu era beta tester dele, mas na verdade nunca cheguei a iniciar os testes...

Abraço,

Paleo. [4/7/07 15:32 - link]

Vinicius Canto : Cara, vai por mim... é muito bom. Se eu continuar fazendo scripts pra ele, já já eu passo da categoria Visual Developer - Scripting para Windows Server - Admin Frameworks

[]s,

Vinicius [5/7/07 23:49 - link]

Anônimo : Ola Vinicius,
Por favor, após ordenar a lista de arquivos por data de criação como posso fazer para apagar arquivos com data acima de um determinado período? [23/7/07 14:56 - link]

Vinicius Canto : Veja essa aqui:

http://viniciuscanto.blogspot.com/2006/12/apagando-arquivos-antigos-no-powershell.html

[]s,

Vinicius Canto
MVP Windows Server - Admin Frameworks [28/7/07 16:39 - link]

Fernando Toledo : Vinicius, parabens pelos seus posts, sempre mto competente.
Estive procurando o vbscript que voce fez que apaga os arquivos antigos e não achei, voce saberia localizar?

Valeu

Abraço [6/11/07 23:09 - link]

Vinicius Canto : Tá na mão:

http://viniciuscanto.blogspot.com/2006/12/apagando-arquivos-antigos-no-powershell.html

[]s,


Vinicius [8/11/07 01:13 - link]

Unknown : Olá vinicius, você que manda no POwer Shellme tira uma dúvida? Como consigo exportar um relatório com os seguintes atributos de vários arquivos: Nome / Tamanho / Data de Criação / Ultimo acesso ?

Qualquer coisa entre em contato.

marcelobitran@hotmail.com [28/10/09 19:10 - link]