2

I have a piece of code that should grab all the .CSV files out of a directory and import them, using pipe character delimiters.

$apeasy = dir .\APEasy\*.csv | Import-CSV -delimiter '|'

The problem is this returns null. Without exception, no matter what I do. The weird thing is that this works:

dir .\APEasy\*.csv

It returns a FileInfo object, which SHOULD be getting piped into Import-CSV as the file to import. In addition, these two commands work:

$csvFiles = dir .\Processed_Data_Review -Filter *.txt | Import-CSV -header(1..19) -delimiter "$([char]0x7C)"
dir .\LIMS -Filter *.csv | Import-CSV | ? {$_.SampleName -like "????-*"}| Export-CSV -Path .\lims_output.txt -NoTypeInformation

I really have no idea what's going on here. I'm dealing with a basic pipe-delimited file, quotations around every field (which is fine, I can import the data with those). Nothing special going on here. The file is THERE, Import-CSV just isn't GETTING it for some reason.

So my question is this: What could cause a file grabbed by 'dir' to fail to be piped into Import-CSV?

EDIT: The overall goal of this is to read the CSV files in a directory without knowing their name in advance, and output specific columns into a variety of output files.

EDIT: This is the line of code as it stands right now:

$apeasy = Get-ChildItem .\APEasy\*.csv | Select-Object -ExpandProperty FullName | Import-CSV -delimiter "$([char]0x7C)"

Isolating the Get-ChildItem statement, and isolating Get-Child and Select-Object both return what they should. A list of csv files in the directory, and an array of their full paths, respectively. Still, when they get piped into Import-CSV, they dissappear. Get-Member on the variable returns that it's empty.

user2543726
  • 23
  • 1
  • 4

3 Answers3

1

Import-Csv accepts only strings (path) from the pipeline so in order to pipe directly to it you need to first expand the paths:

dir .\APEasy\*.csv | 
select -expand fullname |
Import-CSV -delimiter '|'
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
  • The first two parts of this work fine, but Import-CSV returns null all the same. I've updated the question with my implementation of this code. – user2543726 Aug 15 '13 at 15:59
  • Try it against one csv file that has a | delimiter, does it work? Could there be something wrong with your files? – Shay Levy Aug 15 '13 at 16:06
  • I think we might be on the right track. I gave it the file path as a string, still nothing. Checking out the file in various text editors shows that Notepad++ and Excel both recognize the EoL characters, but notepad does not. Other than that, we have a header row on the first line, one record per line, and everything seems correct. – user2543726 Aug 15 '13 at 16:32
  • Final conclusion is that the file I'm importing is UCS-2 Little Endian, and the other files (where it worked) where UTF-8. Now I'm in file encoding territory, which is well documented enough to piece something together. Thanks for the help! – user2543726 Aug 15 '13 at 18:33
  • This approach is effective, but note that it is only necessary to [work around a _bug_](https://github.com/PowerShell/PowerShell/issues/4473). – mklement0 Apr 09 '18 at 01:20
1

Although cmdlets like Get-Content work that way in that they can accept the Path parameter by property name (and LiteralPath by value, which makes sense), Import-Csv is a little inconsistent. It only accepts the path to import by value:

-Path <String[]>
    Specifies the path to the CSV file to import. You can also pipe a path to Import-Csv.

    Required?                    false
    Position?                    1
    Default value                None
    Accept pipeline input?       true (ByValue)
    Accept wildcard characters?  false

So you could use

Get-ChildItem ... | Select-Object -ExpandProperty FullName | Import-Csv

but it won't work out of the pipeline directly.

Joey
  • 344,408
  • 85
  • 689
  • 683
  • I tried this with Path as the property, and it said that "Property 'Path' cannot be found. Also tried it with FullName. No errors, the final object is still null, but replacing Import-CSV with Get-Content returns the insides of the file, so something is happening. This is the bulk of the error, if it helps. + CategoryInfo : InvalidArgument: (U:\GOLEM\APEasy...5.13_8.8.13. csv:PSObject) [Select-Object], PSArgumentException + FullyQualifiedErrorId : ExpandPropertyNotFound,Microsoft.PowerShell.Comm ands.SelectObjectCommand" – user2543726 Aug 15 '13 at 15:10
  • I mis-entered the comment. I tried FullName as well, with the same results. Import-CSV refuses to return anything. – user2543726 Aug 15 '13 at 15:13
0

This is a known bug in Import-Csv - even though you should be able to pipe Get-ChildItem (a.k.a dir) output directly to Import-Csv, that is still broken as of Windows PowerShell v5.1 / PowerShell Core v6.0.2.

Outputting the files' .PSPath property value is a way of working around the problem (.FullName works too) : The input objects' .PSPath property is what should be bound to Import-Csv's -LiteralPath parameter, but currently isn't.

Since you're collecting all input in memory anyway, you can simply use member-access enumeration (PSv3+) to access the .PSPath property on all matching files:

$apeasy = (Get-ChildItem .\APEasy\*.csv).PSPath | Import-CSV -delimiter '|'
mklement0
  • 382,024
  • 64
  • 607
  • 775