Garrett
Garrett

Reputation: 649

Import-Csv and Export-Csv with same name and path

This should be a fairly simple question to answer, but I haven't been able to find a resource online. I need to remove rows from a csv with out changing the filename or path. Currently I am trying to import the file, filter the items I need and export that data to the same location with the same file name:

foreach ($csv in $csvLists){
Import-Csv $csv | Where-Object {[DateTime]$_.'Date' -ge $2WeeksOld} | Export-Csv $csv -NoType -Force
}

Also tried:

foreach ($csv in $csvLists){
Import-Csv $csv | Where-Object {[DateTime]$_.'Date' -ge $2WeeksOld} | Export-Csv $csv.PSParentPath -NoType -Force
}

I am getting access denied errors:

Export-Csv : Access to the path 'D:\Test' is denied.
At C:\script.ps1:20 char:71
+ ... .'Date' -ge $2WeeksOld} | Export-Csv $csv.PSParentPath -NoType -Force
+                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (:) [Export-Csv], UnauthorizedAccessException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ExportCsvCommand

What am I missing here? Is the issue that powershell is reading the file and cant export over it at the same time? Should I try setting the imported data as a variable and then exporting the csv outside the import-csv pipeline?

As always thanks for any help.

Upvotes: 0

Views: 3323

Answers (2)

Bacon Bits
Bacon Bits

Reputation: 32145

The problem here is that you're trying to do everything in one line, and consequently you're opening a file (which locks it) and trying to overwrite the same file (which needs to lock it) at the same time. That won't work.

Try:

foreach ($csv in $csvLists){
    $Data = Import-Csv $csv | Where-Object {[DateTime]$_.'Date' -ge $2WeeksOld}
    $Data | Export-Csv $csv -NoType -Force
}

Or, if $csvLists is an array of FileInfo objects (such as from the output of Get-ChildItem):

foreach ($csv in $csvLists){
    $Data = Import-Csv $csv.FullName | Where-Object {[DateTime]$_.'Date' -ge $2WeeksOld}
    $Data | Export-Csv $csv.FullName -NoType -Force
}

Upvotes: 3

G42
G42

Reputation: 10019

Use $csv.FullName. This contains the full path for a file/folder.
Here are a few common properties of System.IO.FileInfo:

Property        Contents
BaseName        MyFile
Directory*      <returns System.IO.DirectoryInfo object of "C:\Path\To">
Name            MyFile.txt
FullName        C:\Path\To\MyFile.txt
PSParentPath    Microsoft.PowerShell.Core\FileSystem::C:\Path\To

I'm not aware of a use case for .PSParentPath. Looking at the content, I assume it's used when you need to specify the PSProvider as well as the string value of the parent. Otherwise you could just use .Directory.Name

You may find the class definitions for FileInfo and DirectoryInfo useful. They are the objects returned by Get-ChildItem. The links list Methods and Properties; they do not list Code/Note/ScriptProperty types.

tip: run $csv | Get-Member to see members of this object, look at MemberType.

* For System.IO.DirectoryInfo objects, use Parent. Have got some different behaviour in Win10 and am sure an alias was instroduced so that Parent works for FileInfo or Directory works for DirectoryInfo.

Upvotes: 1

Related Questions