martedì 20 giugno 2017

TUTORIAL POWERSHELL - PARTE 9 - FILE

Tutorial introduttivo all'utilizzo di PowerShell, a prima vista una estensione del prompt dei comandi di Microsoft Windows ma che in realtà è molto di più.






Lista completa articoli su Tutorial PowerShell [link]

Leggere File (System.IO.File)

Un'altra funzionalità molto banale che può essere svolta con poche semplici istruzioni è la lettura di un file di testo. 
In ambiente .Net per leggere un file, deve essere prima stabilito un collegamento con il file di tipo Stream (abbiamo accennato il concetto di Stream in un precedente articolo [link]) che viene letto per ottenere il contenuto del file. 

Nell'esempio seguente viene aperto un file C:\test.txt e viene mostrato il suo contenuto.
$filename = "C:\test.txt"
$fs = [System.io.file]::OpenRead($filename)
$reader = new-object System.IO.StreamReader($fs)
while(-not $reader.EndOfStream){
    Write-Output ($reader.ReadLine())
}
$reader.Close()
$fs.Close()

PowerShell offre un cmdlet apposito per la lettura di file di testo, che risparmia la scrittura di tutte queste linee di codice. Utilizzando il cmdlet Get-Content viene restituito un array di stringhe che rappresenta le linee del file. 

L'equivalente del codice di prima assume un aspetto molto più conciso:
$lines = Get-Content C:\test.txt
foreach($line in $lines){
Write-Output $line
}

Attenzione! non è del tutto corretto quello che ho appena detto: la differenza fra l'utilizzare la lettura di un file attraverso lo stream e il cmdlet Get-Content è netta:
  • Aprire un file in lettura tramite lo Stream, lo rende "in uso" e quindi non è possibile eliminarlo (se non viene eseguito il metodo close() rimarrà bloccato fino alla chiusura della sessione PowerShell)
  • Get-Content esegue la lettura preventiva completa del file, dalla prima all'ultima riga, questo significa che utilizzare Get-Content con un grosso file potrebbe interrompere l'esecuzione del programma per alcuni secondi.

Scrivere File (Syste.IO.File)

Specularmente alla lettura del file, la scrittura è una operazione facilmente implementabile attraverso poche semplici righe di codice:
$filename = "C:\test.txt"
$file = [System.io.file]::OpenWrite($filename)
$out = new-object System.IO.StreamWriter($file)
$out.WriteLine("hello")
$out.WriteLine("world")
$out.Flush()
$out.Close()
$file.Close()

Di nuovo, PowerShell mette a disposizione un cmdlet per eseguire la scrittura su un file di testo chiamata Out-File, ma questa volta deve essere utilizzato in pipeline (Abbiamo visto le pipeline in un precedente articolo [link]):
$filename="C:\test.txt"
"hello" | Out-File -Append -FilePath $filename
"world" | Out-File -Append -FilePath $filename

In questo caso PowerShell offre un ulteriore metodo per scrivere su file chiamato reindirizzamento di stream. Il concetto, che era presente già nel prompt dei comandi di Windows, consiste nel reindirizzare l'output di un cmdlet verso un file attraverso l'operatore > (motivo per il quale non è possibile utilizzare il simbolo > durante la comparazione, come abbiamo visto in questo articolo [link])
$filename="C:\test.txt"
"hello" > $filename
"world" > $filename

Attenzione! in questo ultimo caso, a differenza dei primi due, l'output che viene reindirizzato sovrascrive totalmente il contenuto del file.

CSV

Un file CSV (Comma Separated Value [wikipedia]), è un file di testo particolare, per la memorizzazione di dati scritti in successione separati da un carattere (generalmente la virgola (,)) e suddivisi in righe. I file CSV sono uno dei formati di export dei dati più utilizzati grazie alla facilità di scrittura e di lettura, sono anche facilmente letti dai software di ufficio come Microsoft Excel o equivalenti Open Source. PowerShell offre dei cmdlet dedicati ai file CSV.

Per la lettura di file CSV esiste il cmdlet ImportCsv che restituisce un array (righe) di oggetti (colonne); questo comando presuppone che la prima riga contenga l'intestazione (nome delle colonne).

Esempio: supponiamo di avere un file CSV con il seguente contenuto:
"firstColumn","secondColumn","thirdColumn"
1,2,3
4,5,6
7,8,9

$csv = import-csv "C:\example.csv"
$csv[0].firstColumn #this output "1"
$csv[3].thirdColumn #this output "9"

Per scrivere un file CSV invece esiste il cmdlet Export-Csv che può essere applicato in pipeline con altri comandi.

Esempio: supponiamo di voler ottenere un file CSV relativo ad un elenco di file della directory C:\windows con incolonnati nome e dimensione. Utilizzeremo la seguente combinazione di cmdlet:
dir c:\windows -file | select-object -property name,length | export-csv c:\export.csv.

Conclusione

Nel prossimo articolo vedremo come comunicare con un Database Relazionale con PowerShell: prima in maniera tipica della programmazione .Net utilizzando OLEDB e successivamente utilizzando cmdlet specifici.

Nessun commento:

Posta un commento