Masterizzare Import-Csv e Altri Comandi CSV in PowerShell

Il cmdlet Export-Csv di PowerShell e il cmdlet Import-Csv di PowerShell permettono agli amministratori di importare file CSV tramite un ciclo foreach, utilizzando Export-Csv per aggiungere dati a file CSV esportare array in un file CSV e molto altro ancora.

In questo articolo imparerai molti scenari comuni in cui è possibile utilizzare PowerShell per gestire file CSV come:

  • Lettura di file CSV con PowerShell
  • Salvataggio di file CSV con PowerShell
  • Formattazione dell’output prima di eseguire Export-CSV
  • Aggiunta a un file CSV
  • Aggiunta delle differenze a un file esistente
  • Export-CSV e la stringa #TYPE

Se non sei familiare con il funzionamento interno dei file CSV, sono file di testo che seguono un formato standard in cui i valori sono separati da virgole in una tabella. È possibile creare un file CSV in PowerShell utilizzando il cmdlet Export-Csv e inviando in input uno o più oggetti.

Il comando seguente trova i primi due processi in esecuzione e passa gli oggetti generati al cmdlet Export-Csv. Il cmdlet Export-Csv crea quindi un file CSV chiamato processes.csv nella radice dell’unità di sistema (probabilmente C:\).

PS51> Get-Process | Select-Object -First 2 | Export-CSV -Path "$env:SystemDrive\processes.csv"

Ora apri processes.csv con il blocco note. Dovresti vedere "Nome","SI","Handle","VM" in cima come intestazioni. Vedrai anche #TYPE System.Diagnostics.Process, che potrebbe non avere molto senso al momento. Non preoccuparti, affronteremo quella stringa in questo articolo.

Lettura di file CSV con Import-Csv

Vuoi altri consigli come questo? Dai un’occhiata al mio blog personale su PowerShell.

PowerShell ha un paio di comandi che ti consentono di leggere file di testo. Questi comandi sono Get-Content e Import-Csv. Entrambi questi cmdlet leggono tecnicamente il file allo stesso modo. Ma Import-Csv va un passo avanti. Import-Csv comprende la struttura sottostante non solo di un file di testo ma anche di un file CSV.

Dato che un file CSV segue uno schema specifico, Import-Csv comprende lo schema CSV. Questo cmdlet non solo legge il file di testo dal disco, ma converte anche le righe del file CSV in oggetti PowerShell.

File non CSV

In genere, i dati di un CSV sono separati da virgole, ma ci sono momenti in cui un CSV (non tecnicamente un CSV a quel punto) ha dati separati da un diverso delimitatore. Questi delimitatori sono talvolta una tabulazione o forse un punto e virgola.

Se hai un file CSV con un delimitatore diverso, puoi utilizzare il parametro Delimiter. Questo parametro indica a Import-Csv di non cercare le virgole, come fa di default, ma un altro valore.

Ad esempio, se hai un file separato da tabulazioni, puoi leggere il file come segue:

PS51> Import-Csv -Path tab-separated-data.csv -Delimiter "`t"

Aggiunta degli header

A common Import-Csv parameter is Header. This parameter lets you specify the property names of the objects created by this cmdlet.

Di default, il cmdlet Import-Csv considera la riga superiore del file CSV come header. Convertirà quindi questi valori in proprietà di ogni riga (oggetto). Ma se hai un file CSV che non ha una riga di header, puoi utilizzare il parametro Header per definirne uno tu stesso.

Il parametro Header impedisce a Import-CSV di utilizzare la prima riga come header e ti risparmia il fastidio di dover aprire manualmente il file CSV per aggiungere gli header.

Per dimostrare questo comportamento, apri il blocco note e copia/incolla il testo qui sotto. Questo testo rappresenterà un set di dati con tre righe e due colonne.

a,1
b,2
c,3

Salva il file di testo come test.csv. Non dimenticare di abilitare le estensioni dei tipi di file o di racchiudere il file tra virgolette doppie in modo da non salvarlo accidentalmente come un file che termina in .csv.txt!

Ora, utilizza Import-CSV per leggere il file CSV appena creato senza il parametro Header e ispeziona l’output.

PS51> Import-Csv .\test.csv

a 1
---
b 2
c 3

Si noti che viene utilizzata la prima riga come proprietà dell’oggetto. A e 1 non sono “etichette” che desideri per le proprietà dell’oggetto. A, b e c sono lettere mentre 1, 2 e 3 sono numeri. È necessario definirli con il parametro Header come segue:

PS51> Import-Csv .\test.csv -Header "Letter", "Number"

Letter Number
------ ------
a      1
b      2
c      3

Salvataggio di file CSV con PowerShell

Se è necessario creare o salvare un file CSV da oggetti PowerShell, si può procedere anche in modo inverso. Mentre il comando Import-Csv “converte” un file CSV in oggetti PowerShell, Export-Csv fa il contrario. Questo comando “converte” oggetti PowerShell in un file CSV.

Salvando un file CSV con Export-Csv è possibile successivamente visualizzare o utilizzare tali dati in altri sistemi.

Ad esempio, posso salvare tutti i processi in esecuzione sul mio computer utilizzando il comando Get-Process con il comando Export-Csv.

PS51> Get-Process | Export-Csv -Path processes.csv

Il comando Export-Csv è semplice nella sua natura, ma ci sono un paio di cose da tenere d’occhio.

Formattazione dell’output prima di eseguire il comando Export-Csv

Come hai visto sopra, Export-Csv, da solo, effettua una conversione “grezza”. Non aggiunge alcuna formattazione speciale con testo ricco, non aggiunge colori, ecc.

Uno dei problemi più comuni è cercare di rendere l’output più bello prima di esportarlo in un file CSV. Molti utenti cercheranno di migliorare l’aspetto dell’output prima di esportarlo in un file CSV, ma sto per mostrarvi che in realtà peggiorerà le cose.

È possibile aprire un file CSV in Microsoft Excel e applicare corsivo, grassetto, aggiungere colori e molte altre cose, ma se si salva il file come CSV (anziché come un foglio di lavoro Excel), tutte le formattazioni saranno eliminate. Un file CSV semplicemente non è abbastanza “intelligente”.

Ricordate che i file CSV sono solo file di testo semplice con valori delimitati da virgole (o talvolta da tabulazioni). Passare il comando Import-Csv a un cmdlet di PowerShell Format-* non funzionerà come previsto.

Secondo la documentazione di Microsoft Export-Csv: “Non formattare gli oggetti prima di inviarli al cmdlet Export-CSV. Se Export-CSV riceve oggetti formattati, il file CSV conterrà le proprietà di formato anziché le proprietà dell’oggetto”.

Perché è così?

Apri una finestra di PowerShell e crea dei dati di esempio. Utilizziamo l’esempio di Get-Process trattato nella prima sezione di questo articolo. Ma questa volta, assegna l’output a una variabile. Successivamente, invia in pipe gli oggetti di processo al cmdlet Format-Table.

PS51> $a = Get-Process
PS51> $a | Format-Table
Using Format-Table

Puoi vedere che utilizzando Format-Table, otterrai un output pulito e tabulare.

Ora salva questo output in un’altra variabile.

PS51> $b = $a | Format-Table

Ora visualizza le proprietà dei valori delle variabili $a e $b con Get-Member. Questo cmdlet ti aiuterà a capire perché questi due oggetti apparentemente simili non vengono esportati in un file CSV nello stesso modo.

PS51> $a | Get-Member
System.Diagnostics.Process object type
PS51> $b | Get-Member
Format-Table‘s many object types

L’output diretto da Get-Process restituisce: TypeName: System.Diagnostics.Process, mentre l’output da Format-Table è completamente diverso. Restituisce molti tipi diversi con proprietà variabili.

Se si visualizza $a e $b nella console, l’output sembrerà identico. Questo comportamento è dovuto al sistema di formattazione di PowerShell.

Come influisce ciò sull’output di Export-Csv?

PS51> $b | Export-Csv | Format-Table

Export-Csv legge ogni oggetto così com’è. Quando si invia l’output a un cmdlet Format-*, si sta modificando l’input che Export-Csv riceve. Ciò influisce sull’output che viene salvato nel nuovo file CSV.

Se si desidera inviare l’output al cmdlet Export-Csv, non inviare l’output a nessun cmdlet Format-*.

Ricorda che i CSV sono incentrati sui dati, non sulla formattazione.

Aggiunta a un file CSV

A volte si potrebbe avere un file esistente a cui si desidera aggiungere dati anziché crearne uno nuovo. Per impostazione predefinita, Export-Csv sovrascriverà qualsiasi file specificato tramite il parametro Path.

Se è necessario aggiungere dati a un CSV, utilizzare il parametro Append.

Supponiamo di avere un ciclo in cui si desidera salvare ogni oggetto elaborato in un file CSV. Ad ogni iterazione, si ha un oggetto diverso da salvare nel file CSV. Poiché si utilizza ripetutamente il comando Export-Csv, verrà sovrascritto il file CSV se non si utilizza il parametro Append. Senza il parametro Append, si otterrà solo l’ultimo oggetto, il che nella maggior parte dei casi non è l’output desiderato.

L’esempio seguente trova i primi cinque processi in esecuzione. Successivamente, si entra in un ciclo foreach di PowerShell con il comando Import-Csv e si registra le proprietà Name e ProductVersion nel file test.csv uno alla volta.

Get-Process | Select-Object -First 5 | Foreach-Object {
    $_ | Select-Object Name, ProductVersion | Export-CSV -Path C:\test.csv -Append
}

Senza utilizzare il parametro Append, si noterà che nel file CSV sarà presente solo il quinto processo.

Aggiunta di Differenze a un file CSV

È possibile aggiungere solo le differenze di proprietà a un file CSV esistente con il comando Export-Csv. Ciò significa che se le colonne di una riga del CSV e l’oggetto da registrare sono diversi, è possibile aggiungerli.

Per aggiungere solo le differenze al file CSV, è necessario utilizzare i parametri Append e Force insieme. Secondo la documentazione di Microsoft “Quando i parametri Force e Append vengono combinati, gli oggetti che contengono proprietà non corrispondenti possono essere scritti in un file CSV. Vengono scritte nel file solo le proprietà che corrispondono. Le proprietà non corrispondenti vengono scartate”.

Per dimostrare, crea un oggetto con due proprietà: Name e Age.

PS51> $Content = [PSCustomObject]@{Name = "Johnny"; Age = "18"}

Ora crea un altro oggetto con una proprietà Name e Zip.

PS51> $OtherContent = [PSCustomObject]@{Name = "Joe"; Zip = "02195"}

Ogni oggetto ha proprietà diverse.

Successivamente, crea un file CSV dal primo oggetto e cerca di aggiungere il secondo oggetto al CSV senza il parametro Force. Riceverai un errore.

PS51> $Content | Export-CSV -Path .\User.csv -NoTypeInformation
PS51> $OtherContent | Export-CSV -Path .\User.csv -NoTypeInformation -Append
Export-Csv without Force

Tuttavia, se utilizzi il parametro Force, Export-Csv funzionerà correttamente.

PS51> $OtherContent | Export-CSV -Path .\User.csv -NoTypeInformation -Append -Force

Tuttavia, noterai che la colonna Zip è scomparsa nel file CSV. Usa Force con attenzione. Potrebbe non fornire l’output desiderato.

PS51> Import-Csv -Path .\User.csv

Name   Age
----   ---
Johnny 18
Joe

Export-CSV e la stringa #TYPE

Per impostazione predefinita, utilizzando Export-CSV senza parametri aggiuntivi, verrà inclusa una stringa #TYPE all’inizio del tuo file CSV. Questa stringa è seguita dal tipo di oggetto ricevuto da Export-Csv.

#TYPE System.Diagnostics.Process

La maggior parte delle volte, questa stringa non è effettivamente utile durante il consumo dell’output. Questa stringa è presente solo nel caso in cui sia necessario mantenere il tipo di oggetto da cui provengono le proprietà e i valori.

Per rimuovere questa stringa, utilizza il parametro NoTypeInformation. Questo parametro rimuove completamente questa stringa dal CSV.

Si noti che a partire da PowerShell Core, questo non è più necessario.

Sommario

Utilizzando i cmdlet PowerShell Import-CSV e Export-CSV, è possibile lavorare facilmente con file CSV. Questi sono due cmdlet utili che dovresti utilizzare frequentemente quando si lavora con oggetti e file CSV.

La mia speranza è che con le spiegazioni e gli esempi che ho mostrato qui, tu possa avere una chiara comprensione delle situazioni in cui puoi sfruttare questi cmdlet a tuo vantaggio.

Vuoi altri consigli come questo? Dai un’occhiata al mio blog personale su PowerShell.

Source:
https://adamtheautomator.com/import-csv/