Path and string chopping in Powershell - regex

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 = \..\.. in 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?

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.
Remove contained path - $path1.Substring($path2.length)
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…)

Related

In Atom, is there a way to search only in files whose name match a regex?

I use Atom as my primary coding environment, and generally I love it. There is one feature that I could really use right now, and I'm not sure if it exists or not.
Basically, I want to do a project-wide search for a string ("1.1.0"), but I only want to search within files that have the word "build" in them. I know that Atom allows me to search a file/directory pattern, such as src/assets or even src/assets/*.cs or src/assets/buildFile.*
But in this particular project there are tons of files that have the world build - CustomBuild.xml, BuildScript.cs, FinalBuild.xml, etc. Is there any way that I can tell Atom to search for my query string in a regex-defined file/directory pattern? (I'm also open to other ways of solving my problem)
Thank you for your time!
Update: Just to clarify, some things I've tried so far:
Searching using "*build*" for my file/directory pattern (only returns file names that are build.*)
Using */**/*build*.* (same issue)

gitignore all files except all java files in subdirectory

I've tried a bunch of different methods.
1.
*
!.gitignore
!./src/com/AleXander/*
2.
/*
!.gitignore
!src/com/Alexander/*.java
3.
*
!.gitignore
!./*.java
as well as multiple other variations of this. I came across this question that looks like it's using Regex. Is regex needed for this to work? Any ideas?
I also tried these regex patterns but I am not the best at regex.
1.Logic: ignore all files ending with the file extension pattern "java"
*
!.gitignore
!*.[^java$]
2.Logic: ignore all files ending with a "j" followed by an "a" with anything else after that.
*
!.gitignore
!*.j[^a]*
Ignoring * is a bad idea.
This will ignore every file and every directory in every part of your repository.
Especially git will not look at all at ignored directories. Therefore the exceptions you define later will have no effect at all.
There are quite longish include/exclude hacks to make something like this work, but usually the best way is to just explicitly ignore the files you want to ignore and avoid any exceptions whenever possible.
If you feel the need for some more complicated ignore rules this is usually an indicator that your repository layout needs a better structure.

C++ Application using TCL API to enable package autoloading

I want to have my C++ application to enable package autoloading for all ActiveTcl packages in C:\Tcl\lib. I pass below tcl command to Tcl_Eval() in my C++ code. And expect "package require <package name>" will automatically find the package and load it.
set ::auto_path [file join {C:\Tcl\lib}]
But it didn't work as what it does in TCL shell - TCL shell looks for pkgIndex.tcl in auto_path, so when "package require", it can find the right package or shared libs. Is it possible to make it work in C++ application? Or is there any better way?
OK, I think I know what the problem might be. The auto_path is a Tcl list of directories — the code that uses it iterates over the list with foreach — that are searched for packages (and auto-loaded scripts, an old mechanism that I think is rather more trouble than it's worth). Yet you're using a single element, the output of that file join. This wouldn't usually matter on platforms other than Windows, as the directory separator is / there (and that's just an ordinary non-whitespace character to Tcl) but on Windows the directory separator is \ and that's a list metasyntax character to Tcl.
What does this mean? Well, after:
set ::auto_path [file join {C:\Tcl\lib}]
We can ask what the things of that list are. For example, we can print the first element of the list…
puts [lindex $::auto_path 0]
What does that output? Probably this:
C:Tcllib
OOooops! The backslashes have been taken as quoting characters, leaving an entirely non-functioning path. That won't work.
The fix is to use a different way to construct the auto_path. I think you'll find that this does what you actually want:
set ::auto_path [list {C:\Tcl\lib}]
Though this is an alternative (still using list; it's best for trouble-free list construction in all cases):
set ::auto_path [list [file normalize {C:\Tcl\lib}]]
(My bet is that you're trying to use file join as a ghetto file normalize. Don't do that. It's been poor practice for a long time now, especially now that we have a command that actually does do what you want.)

Xcode: How to exclude a path from Search Navigator

In Xcode, in this case 4.x, how would you go about excluding a path (or a path containing a pattern) from search results?
My use case:
My project is SVN controlled. Whenever I search for text (such as a function name), I often get irrelevant results returned from ".svn-base" files (which are used for making local diff's between your working copy and the last checked out revision).
I have setup a custom scope where the 'Location' 'is within the file or folder' 'Classes' (a subfolder I want to search). There doesn't seem to be a way to say "And Not..." or "And where path does not match". There is a "matches regex" and I feel the answer may lie around Look-arounds... Maybe something like (?!\.svn)?
In an extra condition in the settings of my custom scopes I use this:
^((?!\.svn).)*$
Check out this very good explanation here: stackoverflow

In C++ how do i validate a file or folder path?

A user input string for a destination path can potentially contain spaces or other invalid characters.
Example: " C:\users\username\ \directoryname\ "
Note that this has whitespace on both sides of the path as well as an invalid folder name of just a space in the middle. Checking to see if it is an absolute path is insufficient because that only really handles the leading whitespace. Removing trailing whitespace is also insufficient because you're still left with the invalid space-for-folder-name in the middle.
How do i prove that the path is valid before I attempt to do anything with it?
The only way to "prove" the path is valid is to open it.
SHLWAPI provides a set of path functions which can be used to canonicalize the path or verify that a path seems to be valid. This can be useful to reject obviously bad paths but you still cannot trust that the path is valid without going through the file system.
With NTFS, I believe the path you give is actually valid (though Explorer may not allow you to create a directory with only a space.)
The Boost Filesystem library provides helpers to manipulate files, paths and so... Take a look at the simple ls example and the exists function.
I use GetFileAttributes for checking for existence. Works for both folders (look for the FILE_ATTRIBUTE_DIRECTORY flag in the returned value) and for files. I've done this for years, never had a problem.
If you don't want to open the file you can also use something like the access() function on POSIX-like platforms or _access() and friends on Windows. However, I like the Boost.Filesystem method Ricardo pointed out.