Replacing Text in File with name of Folder it is in

Currently, I’ve found this code, that was supposed to change the text in files to file names and I need to modify it to change the text in files to names of folders they are in. I’ve tried using $_.directory.name, but I only get errors.

$files = Get-ChildItem -path C:\Users\ -filter *.json
foreach ($file in $files)
{
$content = Get-Content $file
if ($content -match "placeholder")
{
$content = $content -replace "placeholder", $file.BaseName
Set-Content $file $content
}
}

Denis, welcome to Powershell.org. Please take a moment and read the very first post on top of the list of this forum: Read Me Before Posting! You’ll be Glad You Did!.

When you post code, error messages, sample data or console output format it as code, please.
In the “Text” view you can use the code tags “CODE”, in the “Visual” view you can use the format template “Preformatted”. You can go back edit your post and fix the formatting - you don’t have to create a new one.
Thanks in advance.

You might start with learning the very basics of Powershell first. Without that it will be hard for you to understand the help you get in forums like this.

Because you do not have a pipeline you cannot use the pipeline variable $_. Instead you should use the loop variable - $file in this case - and access whatever property you need - I think “.directory” in this case.

I believe it should be $file.DirectoryName as that only returns the directory name and path in the form of a string (C:\Directory\SubDirectory). If you only want to use the SubDirectory part in your replace you will need tweak it a bit.

Using $file.Directory returns more directory info such as Mode, LastWriteTime and Lenght as well as Name, so you might have to manipulate it a bit to just extract the string value of it. For instance you can do $file.Directory | Select-Object -ExpandProperty Name.

[quote quote=245556]I believe it should be $file.DirectoryName as that only returns the directory name and path in the form of a string (C:\Directory\SubDirectory). If you only want to use the SubDirectory part in your replace you will need tweak it a bit.

Using $file.Directory returns more directory info such as Mode, LastWriteTime and Lenght as well as Name, so you might have to manipulate it a bit to just extract the string value of it. For instance you can do $file.Directory | Select-Object -ExpandProperty Name.

[/quote]

I’ve got a bit of a problem with that. I get an error

Select-Object : Property "Name" cannot be found.

I also think that this code doesn’t search through subfolders, maybe you know how to do that?

You may (re-)read the complete help for Get-ChildItem including the examples to learn how to use it. You may pay special attention to the parameter -Recurse.

In order for the script to search through subfolders as well you need to add the -Recurse switch to the Get-ChildItem command in the first line.

Name should absolutely be a known property.

What happens if you run the following commands on a known file from the Powershell prompt?

Get-ChildItem KnownFile.json
(Get-ChildItem KnownFile.json).Directory
(Get-ChildItem KnownFile.json).Directory | Select-Object -ExpandProperty Name

 

[quote quote=245580]In order for the script to search through subfolders as well you need to add the -Recurse switch to the Get-ChildItem command in the first line.

Name should absolutely be a known property.

What happens if you run the following commands on a known file from the Powershell prompt?

Get-ChildItem KnownFile.json (Get-ChildItem KnownFile.json).Directory (Get-ChildItem KnownFile.json).Directory | Select-Object -ExpandProperty Name

[/quote]
I get the name of the directory…

Currently, code looks like this

$files = Get-ChildItem -recurse -path C:\Users\path\path -filter *.json
foreach ($file in $files)
{
$content = Get-Content $file
if ($content -match "placeholder")
{
$content = $content -replace "placeholder", $file.Directory | Select-Object -ExpandProperty Name
Set-Content $file $content
}
}

My file structure goes like this
Main Folder -> Subfolder that I need the name of -> file 1 with placeholder; file 2 with placeholder; file 3 with placeholder; file 4 with placeholder;

I have multiple subfolders, but it’s only searching for .json files, even if I remove -filter, it tries to find .json files in the main folder, actually finds them, displays an error with path Main folder -> file1 with placeholder; etc. , but says that the path does not exist. Because it doesn’t exist and shell just doesn’t see the subfolder

I get the name of the directory… Currently, code looks like this

$files = Get-ChildItem -recurse -path C:\Users\path -filter *.json
foreach ($file in $files)
{
$content = Get-Content $file
if ($content -match "placeholder")
{
$content = $content -replace "placeholder", $file.Directory | Select-Object -ExpandProperty Name
Set-Content $file $content
}
}

My file structure goes like this Main Folder -> Subfolder that I need the name of -> file 1 with placeholder; file 2 with placeholder; file 3 with placeholder; file 4 with placeholder;

I have multiple subfolders, but it’s only searching for .json files, even if I remove -filter, it tries to find .json files in the main folder, actually finds them, displays an error with path Main folder -> file1 with placeholder; etc. , but says that the path does not exist. Because it doesn’t exist and shell just doesn’t see the subfolder

Sorry, you will need to wrap the $file.Directory | Select-Object -ExpandProperty Name in parenthesis so the entire line looks like this:

$content = $content -replace "placeholder", ($file.Directory | Select-Object -ExpandProperty Name)

If you remove -Filter *.json from the first line the script actually iterates over every file in the Main folder and its subfolders.
Now I’m guessing that the “placeholder”-text only exists in the *.json files which is why those are the ones you’re getting the error from.
If the “placeholder”-text had been a common word such as “the” or similar, you would risk modifying a load of files unintentionally by removing the filter.