Baixe o app para aproveitar ainda mais
Prévia do material em texto
06 Quebra de linha e arrays O resultado do nosso script foi mostrado para um colega do trabalho, antes de ser mostrado para o coordenador. Uma das coisas muito importantes que esse colega comentou a respeito é que a tabela resultante possui a coluna Name — a qual poderia estar em português —, e também uma segunda coluna, mas está sem nome e sim escrito "{0:N2}KB" -f ($_.Length / 1KB). Como uma pessoa leiga saberá o que essa segunda coluna significa? Vamos melhorar isso? O que faremos é: — Traduzir o nome da primeira coluna para o português; e — Trocar o cabeçalho para o nome Tamanho. A primeira coisa a se fazer é jogar o script em um Bloco de Notas e limpá-lo, pois é muito código para uma única linha! Podemos começar utilizando os alias de cada comando. O alias do Where-Object é o ?, e do Select-Object é o select. gci -Recurse -File | ? Name -like "*_migrando_*" | select Name, { "{0:N2}KB" -f ($_.Length / 1KB) } Colaremos esse comando no PowerShell. Se ele retornar o mesmo resultado, é porque tudo está funcionando corretamente. E de fato está! Mas, mesmo utilizando os alias, continua muito código em uma única linha. Então podemos quebrá-la em várias linhas: gci -Recurse -File | ? Name -like "*_migrando_*" | select Name, { "{0:N2}KB" -f ($_.Length / 1KB) } Muito bom! Será que ainda está funcionando? Ué, aconteceu algo muito estranho! Primeiro, foi mostrado todos os arquivos, e depois deu muitos erros. Ora, nós não podemos quebrar um comando de vários comandos encadeados em várias linhas e simplesmente dar um "Enter" e executar. O PowerShell interpreta cada linha como um comando independente. A primeira ação feita foi listar todos os arquivos, pois é isso o que o comando gci -Recurse -File faz. Depois, tivemos vários erros de sintaxe pois ele tentou executar as linhas a seguir com comandos independentes, o que não faz sentido! Depois, ele tentou executar o comando que se encontra na terceira linha, que também deu erro, na quarta linha também, e assim o nosso último script não retornou nada. Para mostrarmos ao PowerShell que não estamos terminando esse comando, e que ele possui mais comandos encadeados, podemos utilizar o backtick, representado pelo acento grave (`): gci -Recurse -File ` | ? Name -like "*_migrando_*" ` | select ` Name, ` { "{0:N2}KB" -f ($_.Length / 1KB) } Repare que não usamos o backtick na última linha, mas sim somente nas anteriores do comando. Executaremos novamente esse comando no PowerShell, porém utilizando o backtick. Maravilha! Agora o nosso comando está funcionando! Mas, por mais que funcione com o backtick no final de nossos comandos, quando temos um comando pipe (|) que passará o resultado da expressão seguinte, o PowerShell é inteligente o suficiente de esperar a próxima linha, sempre que ele encontra um pipe no final. Sendo assim, podemos trocar aqueles backticks pelos pipes no final das linhas. Vamos executar dessa forma! PS C:\Scripts> gci -Recurse -File | >> ? Name -like "*_migrando_*" | >> select ` >> Name, ` >> { "{0:N2}KB" -f ($_.Length / 1KB) } E, podemos ver que ele funciona da mesma forma, e essa é uma boa convenção. Caso venhamos a quebrar os comandos, deixaremos o pipe no final. E quando for quebrar argumentos, podemos usar o backtick, assim como fizemos no select. Podemos melhorar ainda mais a legibilidade do select, separando seus argumentos em várias variáveis. Lembrando que a sintaxe do select é que ele recebe por parâmetro um array de objetos. Então, separaremos o primeiro objeto Name e nomeá-lo como $nameExpr de "expressão" e que, na verdade, ele é uma string "Name". Faremos a mesma coisa com a expressão do Length. $nameExpr = "Name" $lengthExpr = { "{0:N2}KB" -f ($_.Length / 1KB) } gci -Recurse -File | ? Name -like "*_migrando_*" | select ` $nameExpr, $lengthExpr Vamos copiar todo esse código, e colar no PowerShell. Maravilha! Substituímos por variáveis, e ele continua funcionando da forma que esperamos. Agora, podemos dar um passo além. Sabemos que o select recebe por parâmetro um array! E algo que já vimos nesse curso mas ainda não comentamos é a respeito da vírgula. A vírgula indica para o PowerShell que estamos montando um array. Por essa razão que o select está funcionando quando colocamos esses dois valores e uma vírgula. Ele sabe que ele deve mostrar as colunas de acordo com os objetos desse array. Faremos um teste no PowerShell. Se queremos um array de números, por exemplo, usamos a vírgula para separar cada número: PS C:\Scripts> 1, 2, 3 1 2 3 E como podemos ter a certeza de que o que temos aqui é um array? Podemos colocar entre parênteses e verificar o GetType().name, já que é um objeto .net: PS C:\Scripts> (1, 2, 3).GetType().name Object[] E então, foi retornado um Object[] indicando que temos um array! E se temos um array de somente um item? Podemos colocar dessa forma (1).GetType().name e pegar o seu nome? Infelizmente não. Se temos um array de somente 1 item, não podemos esperar que o PowerShell interprete isso como um array. Ele interpretará isso como uma expressão, e como não há vírgulas, ele entende que estamos tratando do número literal 1. Existe um truque que podemos usar para enganar o PowerShell, que é colocando uma vírgula antes do número 1 dentro dos parênteses, dessa forma: PS C:\Scripts> (,1).GetType().name E de fato, ele entende que isso é um array com 1 elemento. Mas ainda existe outro problema: e se precisarmos passar como argumento uma lista de objetos vazia? Podemos colocar ().GetType().name? Não, isso terá um erro de sintaxe. O mesmo acontece se quisermos colocar a vírgula dentro dos parenteses: (,).GetType().name, também não vai dar certo! Nesses casos, é preciso indicar explicitamente que queremos um array. Para isso, basta colocarmos como primeiro caractere, um @ antes dos parênteses. Assim, indicamos que existe um array: PS C:\Scripts> @().GetType().name Isso também se aplica para o array de somente um objeto, e isso vai da preferência de cada administrador ou desenvolvedor. Vamos alterar o nosso script. Adicionaremos uma nova variável: $nameExpr = "Name" $lengthExpr = { "{0:N2}KB" -f ($_.Length / 1KB) } $params = ($nameExpr, $lengthExpr) gci -Recurse -File | ? Name -like "*_migrando_*" | select $params Vamos copiar todo esse código, e colar no PowerShell. Ele continua funcionando. Agora que limpamos o código, é preciso resolver do Length e Name! Vamos lá? 06 Quebra de linha e arrays
Compartilhar