Buscar

06 - Quebra de linha e arrays - Transcrição

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

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

Outros materiais