Path and string chopping in Powershell

I'm doing some work involving some automated file moving, and these files contain relative paths that must be maintained. Unfortunately, I'm finding the facilities offered by System.IO.Path, System.String, and Powershell's operators to be a little ill-equipped to handle my work gracefully.

One function that would be very useful to me is the notion of a subtraction of paths, that would work in theory like subtracting vectors. Conceptually, A - B gets you a path from B to A. In the application to paths,D:\A\B\C\D - D:\A\B\ = \C\D. Likewise,D:\A\B\ - D:\A\B\C\D = \..\ this case. I can accept, for now, that this only makes sense when one path is wholly contained in the other.

This seems to consist of two steps: 1) determine containment of one path in the other. 2) remove the contained path from the containing path. 3) Optionally, replace folder names with the parent .. symbol based on the sidedness of the operation.

As I am concerned with NTFS, I need both containment and replacement operations to be case-insensitive. For containment, I can use select-string since it is case-insensitive, and allows the -simple switch which allows me to use a path without hacking it apart to escape them for regex.

Removing the string from the other is a little more annoying though. System.IO.Path has nothing for this, System.String's pertinent methods are all case-sensitive, and powershell's operators all require massaging so that the regex will match things.

All this seems like more work than it should be--are there any tools I'm missing that would better handle this?

  1. Determine containment - convert your paths to absolute paths (if not already). You can use Resolve-Path for this. Then you can use $path1.StartsWith($path2, 'OrdinalIgnoreCase') to test for containment.

  2. Remove contained path - $path1.Substring($path2.length)

  3. Replace parent folder names with ... - although I don't have the regex off the top of my head, I'm pretty sure you could do this with a regular expression search/replace using PowerShell's -replace operator

filedirectorypath, on CodePlex, may offer what you need

It's not a PowerShell specific API, but that's no reason not to use it from PowerShell.

Benefits of the NDepend.Helpers.FilePathDirectory over the .NET Framework class System.IO.Path include:

  • Strongly typed File/Directory path.
  • Relative / absolute path conversion.
  • Path normalization API
  • Path validity check API
  • Path comparison API
  • Path browsing API.
  • Path rebasing API
  • List of path operations (TryGetCommonRootDirectory, GetListOfUniqueDirsAndUniqueFileNames, list equality…)
What Others Are Reading