Bill Hurt
Bill Hurt

Reputation: 749

Output to Pipeline from within IF ELSE statement

UPDATE: I just found out that the client I am running this on is PS V1. I can't use splatting.

I have a script for processing csv files. I don't know ahead of time if the file will have a header or not so I'm prompting the user to either input a header or use the one in the file:

$header = Read-Host 'Input your own header?'

What I want to do is be able to check whether the header variable has been set to decide if I want to use that flag when executing the Import-CSV commandlet.

I have tried a number of things along the lines of:

IF($Header){Import-Csv $File -delimiter $delimiter -Header $header }
ELSE 
{Import-Csv $File -delimiter $delimiter} |

Or

IF($Header){Import-Csv $File -delimiter $delimiter -Header $header | %{$_} }
ELSE 
{Import-Csv $File -delimiter $delimiter | %{$_}}

The first example results in complaints of an empty pipeline. The second results in the first column of the file just being ouptut to the console and then errors when the file is done processing because the rest of the pipeline is empty.

As always any help would be appreciated.

Thanks, Bill

Upvotes: 1

Views: 894

Answers (3)

Keith Hill
Keith Hill

Reputation: 201832

You second approach is the way I would go. I'm not sure why, what you have shown for your second example, would be failing. Here is what I would do:

filter ProcessCsv {
    $_ | ... further processing ...
}

$header = Read-Host 'Input your own header?'
if ($header) {
    Import-Csv $file -Delimiter $delimiter -Header $header | ProcessCsv
else {
    Import-Csv $file -Delimiter $delimiter | ProcessCsv
}

Upvotes: 1

Eris
Eris

Reputation: 7638

The easiest way is just to use the -OutVariable option on Import-Csv

Import-Csv -Path:$File -Delimiter:$Delimiter -OutVariable:CSVContents will save it in $CSVContents

From the Import-CSV Technet page:

This cmdlet supports the common parameters: -Verbose, -Debug, -ErrorAction, -ErrorVariable, -OutBuffer, and -OutVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/p/?LinkID=113216).

Another alternative is to use an args hash and "splat" it:

$myArgs = @{
    Path = "$HOME\temp\foo"
}

Get-Content @myArgs

Update for Version 1 (untested):

( IF($Header) { Import-Csv $File -delimiter $delimiter -Header $header }
  ELSE { Import-Csv $File -delimiter $delimiter} ) |
#More pipeline commands here, example:
Format-Table

Horrible disgusting version (untested):

$ImportCommand = "Import-Csv $File -delimiter $delimiter"
If($header -ne $null) { $ImportCommand += " -header $header" }
Invoke-Expression $ImportCommand | 
Format-Table

Upvotes: 2

KevinD
KevinD

Reputation: 3163

Eris already suggested splatting, but I wanted to give a more comprehensive example, using your code.

# Declare a hash containing the parameters you will always need 
$csvParams = @{
    File = $File;
    delimiter = $delimiter;
}

# if the header is specified, add a Header to $csvParams
if ($Header) { $csvParams.Header = $header }

# Call Import-Csv, splatting $csvParams
Import-Csv @csvParams

Splatting is an extremely useful technique. Get-Help about_Splatting for more information about it.

Upvotes: 4

Related Questions