Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell Get Parent Folder of a File

Tags:

powershell

I'm writing a script which archives files for analysis. My issue is that the file names aren't unique over multiple folders so they are being over written.

For instance:

C:\StuffToCopy\Folder1\myFile1.txt
C:\StuffToCopy\Folder1\myFile2.txt
C:\StuffToCopy\Folder2\myFile1.txt
C:\StuffToCopy\Folder2\myFile2.txt

At the end of my copy process I'm only getting 2 files, but I want 4.

I'd like the output to be like this:

C:\ArchiveCopy\Folder1_myFile1.txt
C:\ArchiveCopy\Folder1_myFile2.txt
C:\ArchiveCopy\Folder2_myFile1.txt
C:\ArchiveCopy\Folder2_myFile2.txt

Here's my script so far.

$files = dir -r -path "C:\StuffToCopy\" -i *.*

foreach ($file in $files)
{
    if ($file.LastWriteTime -gt (get-date).AddDays(-1)) {
        copy -path $file C:\ArchiveCopy\
    }
}

I want to do something like copy -path $file.FolderName & '_' & $file C:\ArchiveCopy\

I'm just not sure how to do it.

like image 229
Mike Mengell Avatar asked Sep 16 '11 13:09

Mike Mengell


People also ask

How do I go to parent directory in PowerShell?

Use Split-Path Cmdlet to Get the Parent's Parent Directory in PowerShell. The Split-Path cmdlet displays the specified part of a path. It can be a parent folder, subfolder, file name, or file extension. The default is to return the parent folder of the specified path.

How do I get the directory of a file in PowerShell?

PowerShell utilizes the “Get-ChildItem” command for listing files of a directory. The “dir” in the Windows command prompt and “Get-ChildItem” in PowerShell perform the same function.

What is Get-ChildItem in PowerShell?

Description. The Get-ChildItem cmdlet gets the items in one or more specified locations. If the item is a container, it gets the items inside the container, known as child items. You can use the Recurse parameter to get items in all child containers and use the Depth parameter to limit the number of levels to recurse.

What is split path in PowerShell?

The Split-Path cmdlet returns only the specified part of a path, such as the parent folder, a subfolder, or a file name. It can also get items that are referenced by the split path and tell whether the path is relative or absolute. You can use this cmdlet to get or submit only a selected part of a path.


2 Answers

If $file is really a file – an instance of System.IO.FileInfo (and not really a directory: System.IO.DirectoryInfo) then it has property Directory which is an instance of DirectoryInfo which has a Name:

$file |
  copy-item -destination { 
     Join-Path C:\ArchiveCopy\ -childpath ($_.Directory.Name + "_" + $_.Name) }

(Using a pipeline to start because the -LiteralPath parameter of Copy-Item will bind to the PSPath property from the pipeline, so no need to pull the original file's name from the $file object.)

If $file might be a directory, then you need to do more of the work yourself, but probably easier to filter out directories first:

dir -r -path C:\StuffToCopy\ |
  where { -not $_.PSIsContainer } |
  copy-item -destination { 
     Join-Path C:\ArchiveCopy\ -childpath ($_.Directory.Name + "_" + $_.Name) }

Note:

  • No need to save all the file objects and then loop over them: let the pipeline do the looping
  • No need to -i "*.*": this is the default anyway (and if you need to filter files on a wildcard pattern prefer the -filter pattern parameter: the filter is passed to the filesystem rather than creating .NET objects and then filtering them which is much slower if there are a lot of files).
like image 200
Richard Avatar answered Sep 23 '22 11:09

Richard


Try this:

dir -r -path C:\StuffToCopy | 
        where {!$_.psiscontainer} | 
        copy -dest { "C:\ArchiveCopy\$($_.Directory.Name)_$($_.Name)"}
like image 24
Shay Levy Avatar answered Sep 19 '22 11:09

Shay Levy