Powershell script and blank spaces... seeking elegance and maybe comprehension

I don’t do much scripting and wanted to know what I could do to make the script I came up with more elegant in powershell. TBH, I’m a little baffled why powershell is keeping a space unless I select a non-spaced space.

Explanation:
I had a flat directory with file names which included where these files came from. Let’s say the origins are listed as X1, X2, … I decided to place all these files into their respective directories. For example, “X1 Title.pdf” → directory entitled “X1” with the file still named “X1 Title.pdf”.
I wanted to remove the "X1 " (including the blank space) from the file name using powershell.
The following command works:
get-childitem -recurse -file -filter *pdf | Rename-Item -NewName { $.Name -replace $.Directory.Name + “”, “” }

BUT:

  1. get-childitem -recurse -file -filter *pdf | Rename-Item -NewName { $.Name -replace $.Directory.Name + " ", “” }

(adding to search for a blank space after the directory name)
Seemingly this is expecting 2 spaces after the X1 (directory name) and thus does not rename anything.

  1. get-childitem -recurse -file -filter *pdf | Rename-Item -NewName { $.Name -replace $.Directory.Name, “” }

Here I removed the + " " (or just use the + without any quotes afterwards), and the result is to have a blank space as the first character in the file name.

So I’m a little confused. If I specify a blank space, it expects 2 blank spaces. If I don’t specify a space after the directory name, it retains the blank space.
The only thing that works is to add a non-spaced space (i.e., “”) after the directory name.

As I wrote above, I figured out what code works for what I want, but if someone would be kind enough to either explain to me why I need the ’ + “” ’ or to provide a more elegant way to indicate the search to also include blank spaces, I’d appreciate it.

thanks!

So -replace uses regex implicitly, not sure if you knew that. I don’t understand why it would since it’s not valid regex but it looks like that "" is matching the space character. $_.Directory.Name+".*" functions the same and is what I would expect to be required. I really have to question whether this is intended behavior. Looking at the Powershell source code it looks like it just uses .NET library pretty simply.

public object Replace(string input)
{
    if (_cachedReplacementString is not null)
    {
        return _regex.Replace(input, _cachedReplacementString);
    }

    Dbg.Assert(_cachedMatchEvaluator is not null, "_cachedMatchEvaluator should be not null when code reach here.");
    return _regex.Replace(input, _cachedMatchEvaluator);
}

There is definitely some weird interaction going on here though.

MS Regex is a little different in .NET than the standard regex in other languages.

Try this, put your $.Directory.Name in double quotes and include your space in that.

 get-childitem -recurse -file -filter *pdf | Rename-Item -NewName { "$.Name" -replace "$.Directory.Name ", “” }

Some of the features in .NET automatically trim the input which will make it hard to work with some string manipulation. I have had success making sure that the trailing space will be included if I wrap what I am looking for in quotes. This is exacerbated by Powershell to assume that everything is an object unless explicitly cast otherwise.

**Edit
Also adding a string + “something” treats them like separate objects a lot of the time. This can be visualized by using the echo command and seeing what your output looks like. Every + automagically includes a carriage return because it treats the plus like a logical AND that separates the command, ie Print X AND Print Y