powershell- recursive call to rename file names in bulk - powershell

I am trying renaming the files recursively.
My sample file name is:
2011.02.21 Work Plan - Greg Graham_v1.0__977a6c84-340a-442f-997e-aea94308b382.pdf
I want to delete the string __977a6c84-340a-442f-997e-aea94308b382 which starts with two underscore + 36 characters of identifier.
So result filename will be :
2011.02.21 Work Plan - Greg Graham_v1.0.pdf
All the files are in the mentioned folders or subfolders.
I am using following PowerShell :
Get-ChildItem -Path E:\Recover\test -Recurse | Rename-Item -NewName{$_.name -replace{$_.name.SubString({$_name.IndexOf("__")},38)},""}
When I was using -WhatIf then it shows all the files. But if I use without -WhatIf . It doesn't delete anything.
With-WhatIf it shows both target and destination filenames same.
Appreciate your help.

I think you'd be better off with a regex match. Something like:
GCI $path -recurse | Where{$_.BaseName -match "(.+?)__.{36}$"} | ForEach{Rename-Item -Path $_.FullName -NewName "$($Matches[1])$($_.extension)"}
That will capture the beginning of the file's name (assuming the file name without extension ends in two underscores followed by 36 characters), and then rename the file based on that capture, and the file's original extension.

Related

Powershell - Search for Pattern and Copy

i have a bunch of *.CSV Files. Huge *.CSV Files. I try to search for a specific pattern in these Files called "Secure". If found, the script shall copy it to a folder.
It works, but it has one Problem i could'nt solve.
In some files, the Word i'm looking for is present more than once. Now my script searches for the word, finds it and copies it. Then it searches in the same file again, finds the pattern again and copies again.
But it should copy after the first find of the word and then search in the next *.CSV file and not in the same again.
i tried a bunch of things "-SimpleMatch" or "-First 1"
the Code so far is :
Select-String -Path 'C:\Tools\Test\*\*.csv' -Pattern "Secure" | Select -first 1 | Copy-Item -Destination C:\Tools\Found -Verbose
can someone help me ?
Thank you!
Use Get-ChildItem to discover the initial set of files, then use Select-String on one file at a time. This way Select -First 1 will return after the first match in each file, rather than breaking the whole pipeline after outputting the first file:
Get-ChildItem -Path 'C:\Tools\Test\*\*.csv' |Where-Object { $_ |Select-String -Pattern "Secure" |Select -First 1 } |Copy-Item -Destination C:\Tools\Found -Verbose

Renaming a Directory with wildcard on Powershell?

I have a folder that needs to be renamed.
$home/dir1/dir_to_rename_12344343
$value=abcd-1234
I know the beginning pattern of the folder but not the whole name.
I was trying to do something like this
cd $home/dir1
Rename-Item 'dir_to_rename*' '$value'
but it keeps giving me an error.
I am also happy if I can just trim the last few chars of the folder name.
i.e., $home/dir1/dir_to_rename_12344343 --> $home/dir1/dir_to_rename
I was finally able to get it to work
Get-ChildItem -Path $home/dir1 | Rename-Item -NewName $Value

How to prevent PowerShell -Recurse from renaming first file twice?

When using powershell to rename files with their directory name and file name, my code works, except in the first file in a directory, it gives it two copies of the directory name. So the file book1.xlsx in folder folder1 should become folder1book1.xlsx but it becomes folder1folder1book1.xlsx. The remaining files in folder1 are correctly named folder1book2.xlsx, folder1book3.xlsx, etc.
I have a directory, with many sub-directories. In each sub-dir are files that need their sub-dir name added in.
I've been following this code. For me it looks like:
dir -Filter *.xlsx -Recurse | Rename-Item -NewName {$_.Directory.Name + "_" + $_.Name}
I've also tried
--setting the Recurse -Depth 1 so that it doesn't keep looking for folders in the sub-folders.
--using ForEach-Object {$_ | ... after the pipe, similar to this.
--running it in Visual Studio Code rather than directly in PowerShell, which turns it into:
Get-ChildItem "C:\my\dir\here" -Filter *.xls -Recurse | Rename-Item -NewName {$_.DirectoryName + '_' + $_.Name}
--putting an empty folder inside the sub-directory, setting -Depth 2 to see if that will "catch" the recurse loop
I would expect the files to be named folder1_book1.xlsx, folder1_book2.xlsx, folder1_book3.xlsx.
But all of the attempted changes above give the same result. The first file is named folder1_folder1_book1.xlsx [INCORRECT], folder1_book2.xlsx[CORRECT], folder1_book3.xlsx[CORRECT].
A workaround might be writing an if statement for "not files that contain the sub-directory name" as suggested here. But the link searches for a text string not an object (probably not the correct term) like #_.Directory.Name. This post shows how to concatenate objects but not something like #_.Directory.Name. Having to put in an if statement seems like an unnecessary step if -Recurse worked the way it should, so I'm not sure this workaround gets at the heart of the issue.
I'm running windows 10 with bootcamp on a 2018 iMac (I'm in Windows a lot because I use ArcMap). Powershell 5.1.17134.858. Visual Studio Code 1.38.0. This is a task I would like to learn how to use more in the future, so explanations will help. I'm new to using PowerShell. Thanks in advance!
This was a script I created for one of my customers that may help
<##################################################################################################################################
This script can be used to search through folders to rename files from their
original name to "filename_foldername.extension". To use this script
please configure the items listed below.
Items to Congfigure
-$Original
-$Source
-$Destination
-$Files
Also please change the Out-File date on line 29 to today's date ****Example: 2019-10-02****
We've also added a change log file that is named "FileChange.txt" and can be found in the location identified on line 30
>
$Original="C:\temp\test" #Location of ".cab" files copied
$Source="C:\temp\Test" #Location were ".cab" files are stored
$Destination="C:\temp\Test\2019-10-02" #Location were you want to copy ".cab" files after the file name change. Be sure to change the date to the date you run this script. The script creates a folder with todays date
$Files=#("*.cab") #Choose the file type you want to search for
$ErrorActionPreference = "SilentlyContinue" #Suppress Errors
Get-ChildItem $Original -Include "*.cab" -File -Recurse | Rename-Item -NewName {$_.BaseName+"_"+$_.Directory.Name +'.cab'}
New-Item -ItemType Directory -Path ".\$((Get-Date).ToString('yyyy-MM-dd'))"; Get-ChildItem -recurse ($Source) -include ($Files) | Copy-Item -Destination ($Destination) -EA SilentlyContinue
Get-ChildItem $Original | Where {$_.LastWriteTime -ge [datetime]::Now.AddMinutes(-10)} | Out-File C:\temp\test\2019-10-02\FileChange.txt

rename file.jpg.jpg to file.jpg using powershell

I inadvertently named over a thousand files as filename.jpg.jpg. My desired end state is to have the file name as filename.jpg. How can I use PowerShell to fix this?
I have tried many examples from blogs and find that the first .jpg is apparently being seen as the file extension. Any assistance would be greatly appreciated as my only alternative is to manually rename all the files.
Try this,
Get-childItem constant* | % {rename-item $_.name ($_.name -replace '.jpg.jpg','.jpg')}
it will replace .jpg.jpg to .jpg
You could use the Get-ChildItem cmdlet to retrieve the files and prefilter it using the -Filter parameter.
You should use the FullName property instead of the Name for the Rename-Item cmdlet whenever your working directory is a diffrent one.
The regexI use here escapes the periods (mentioned by Matt) and also ensures to match the end of the filename ($).
Get-ChildItem -Path 'YOUR_PATH_HERE' -Filter '*.jpg.jpg' |
foreach { Rename-Item $_.FullName ($_.FullName-replace '\.jpg\.jpg$','.jpg') }
Note: If you need to recursively rename the files, you just need to add -recurse to the Get-ChildItemcmdlet.

Rename first 20 characters of every filename in a file

I am trying to write a script in powershell to remove the first 20 characters of every MP3 filename in a folder, I have created a file 'test.ps' and inserted the powershell code below into it,
gci *.mp3 | rename-item -newname { [string]($_.name).substring(20) }
When I run this file in powershell.exe nothing happens,
Can anyone help? Thanks.
This may get you started. (There are probably much more concise ways, but this works and is readable when you need to maintain it later. :-) )
I created a folder C:\TempFiles, and created the following files in that folder:
TestFile1.txt
TestFile2.txt
TestFile3.txt
TestFile4.txt
(I created them the old-fashioned way, I'm afraid. <g>. I used
for /l %i in (1,1,4) do echo "Testing" > TestFile%i.txt
from an actual command prompt.)
I then opened PowerShell ISE from the start menu, and ran this script. It creates an array ($files), containing only the names of the files, and processes each of them:
cd \TempFiles
$files = gci -name *.txt
foreach ($file in $files) {
$thename = $file.substring(4);
rename-item -path c:\TempFiles\$file -newname $thename
}
This left the folder containing:
File1.Txt
File2.Txt
File3.Txt
File4.Txt
File5.Txt
In order to run a script from the command line, you need to change some default Windows security settings. You can find out about them by using PowerShell ISE's help file (from the menu) and searching for about_scripts or by executing help about_scripts from the ISE prompt. See the sub-section How To Run A Script in the help file (it's much easier to read).
Your code actually works. Two things...
Rename the file to test.ps1.
Run it in the folder you have your MP3 files in. Since you didn't provided a path to Get-ChildItem it will run in the current directory.
I tested your line by making a bunch of mp3 files like this -
1..30 | % { new-item -itemtype file -Name (
$_.ToString().PadLeft(30, 'A') + ".mp3" )}
I would use a more "safer" way (you'll get an error if the file name is shorter than the length in question, you are also targeting the file extension as a part of the total characters). Check if the base name of each file is greater than 21 characters (if you remove the first 20 it can be still have a name with one character long). It can fail if the directory contains a file with same name after you removed the first 20, you can develop it further on your own):
gci *.mp3 | foreach{
if($_.BaseName.Length -ge 21)
{
$ext = $_.Extension
$BaseName = $_.BaseName.Substring(20)
Rename-Item $_ -NewName "$BaseName$ext"
}
}
// delete (replace with empty char) first 20 charters in all filename witch is started with "dbo."
// powershell
Get-ChildItem C:\my_dir\dbo -Recurse -Force -Filter dbo.* | Where-Object {!$_.PSIsContainer} | Rename-Item -NewName { ($_.name).Substring(20) }