Can't replace file names with PowerShell 2.0 - powershell-2.0

I have files like this.
[mix]aaaa.flv
[mix]aaaa.mpv
[mix]aaaa.ogv
[mix]aaaa.webm
[mix]bb.flv
[mix]bb.mpv
[mix]bb.ogv
[mix]bb.webm
...
I just need to remove "[mix]" from the file names.
I use this command, but failed
Dir | Rename-Item –NewName { $_.name –replace "[mix]", "" }
Error says
Rename-Item : 'Microsoft.PowerShell.Core\FileSystem::C:\Users\Desktop\[mix]aaaa.mp4'에 항목이 없으므로 이름을 바꿀 수 없습니다.
위치 줄:1 문자:18
+ Dir | Rename-Item <<<< –NewName { $_.name –replace “[mix]“,”” }
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand
There's korean in error code, it might say : Can't change name, there is no item at 'Microsoft.PowerShell.Core\FileSystem::C:\Users\Desktop\[mix]aaaa.mp4'
And I don't understand what I'm doing wrong. I used to change file names with this command.

I think this is a known bug with Rename-Item and powershell 2.0
What I did was to use Move-Item instead, you should be able to use the following (tested on powershell 2.0):
Dir | Move-Item -Destination {$_.Name -replace "\[mix\]", ""}

I was able to make this work. Remember that [ and ] are regex metacharacters and need to be escaped:
Dir | Rename-Item -NewName {$_.Name -replace "\[mix\]",""}

Related

Powershell: batch rename files, add counter in front (with leading 0)

I am trying (as so many others) to batch rename files in a folder, by adding a counter to the front of the filename with leading zeros.
Here is what I have:
b.txt
c.txt
...
zzz.txt
Here is what I want:
001_b.txt
002_c.txt
...
893_zzz.txt
My code so far:
$originalFiles = Get-ChildItem "C:\Users\abc\" -Filter *.txt
$i = 1
ForEach ($originalFile in $originalFiles) {
Rename-Item -Path $originalFile.FullName -NewName (($originalFile.Directory.FullName) + "\" + $i + $originalFile.Name)
$i++
}
I am missing the underscore between the the number and the filename. And I am missing the leading zeros.
Any suggestions are welcome.
Sorry for this basic question, this is my first PowerShell experience.
This should do the trick:
$MyPath = "C:\Users\abc\"
$i=1
Get-ChildItem -Path $MyPath -Filter "*.txt" | Sort-Object | ForEach-Object {
Rename-Item -Path $_.FullName -NewName (Join-Path -Path $_.Directory.FullName -ChildPath "$('{0:d3}' -f $i)_$($_.Name)")
$i++
}
Keep in mind that if you will have 1000 or more files, you will need more than 3 digits

Rename files with same name and extension (usually .pdf) in the sub directories with incrementing number

My folder structure is like this:
Folder 1
File 1.pdf
File 2.pdf
File 3.pdf
Folder 2
File 1.pdf ---> Rename this to "File 1-1.pdf"
File 2.pdf ---> Rename this to "File 2-1.pdf"
File 5.pdf
SubFolder 2.1
File 2.pdf ---> Rename this to "File 2-2.pdf"
File 4.pdf
File 5.pdf ---> Rename this to "File 5-1.pdf"
Folder 3
File 1.pdf ---> Rename this to "File 1-2.pdf"
File 2.pdf ---> Rename this to "File 2-3.pdf"
File 4.pdf ---> Rename this to "File 4-1.pdf"
File 6.pdf
File 7.pdf
This is what i was trying, but its certainly wrong. I am using Powershell Version 2.0.
$i = 1
$folder = Get-ChildItem "C:\Users\xyz\testfolder\pdf_files\"
foreach ($file in $folder){
if (($file.BaseName + $file.extension) -match ($file.BaseName +
$file.extension)){
Rename-Item -Path $file.FullName -NewName "$($file.BaseName +
$i)$($file.extension)" -Verbose -WhatIf
$i++
}
}
I just found the answer to my question through a very kind person. Anyway..here is the PS script that worked for me..
$Files = Get-ChildItem -LiteralPath 'C:\Foo\Bar\Files\' -Recurse | Where-
Object { -not $_.PSIsContainer }
$FileNameCounts = #{}
ForEach ($File In $Files) {
$BaseName = $File.BaseName
If ($FileNameCounts.Keys -contains $BaseName) {
$NewName = '{0}-{1}{2}' -f $BaseName, $FileNameCounts[$BaseName],
$File.Extension
$File | Rename-Item -NewName $NewName -WhatIf
$FileNameCounts[$BaseName]++
} Else {
$FileNameCounts[$BaseName] = 1
}
}
Here is an alternative way of doing the same thing.
Get-ChildItem -Recurse -file | Group-Object Name | foreach-object {
$script:i = 1
$_.Group | Select-Object -Skip 1 |
Rename-Item -newname { "{0}-{1}{2}" -f $_.basename, $script:i++, $_.extension }
}
Group-Object gives us all the files with the same name, and for each group of names, the first file is skipped and the rest is being renamed.
It also takes advantage of a feature that was designed specifically for this usecase, that -NewName can take a scriptblock as a parameter. The scriptblock will be invoked for each pipeline item and the result will be passed to Rename-Item as the newname.

powershell v2 - rename a file whose name matches a string containing a wildcard

I'm trying to create a script to rename a file that matches a given filename, with a wildcard character. e.g.
I have a folder containing the following files:
201412180900_filename_123.log
201412181000_filename_123.log
201412181100_filename_456.log
filename_789.log
I want to scan through this folder, and append the current time to the start of any file starting with the word 'filename'
I have the following so far:
$d = Get-Date -format "yyyyMMddHHmm"
$dir = "C:\test"
$file = "filename*.log"
get-childitem -Path "$dir" | where-object { $_.Name -like "$file" } | rename-item -path $_ -newname $d."_".$_.name
but it doesn't work.
As I see it the individual sections 'should' work from my reading of the documentation, but clearly something is wrong. If someone can point it out it would be appreciated.
We're getting closer. It would appear that -path in the rename-item section needs to be $dir$_ as $_ (seemingly) only contains the filename. (The get-help example suggests it needs to be the full path and filename)
If I take out the rename-item section and replace it with %{write-host $d"_"$_} it gives the correct new filename
However, simply placing this into rename-item section still doesn't update the filename.
rename-item -path $dir$_ -newname $d"_"$_
SUCCESS
the correct syntax appears to be:
get-childitem -Path "$dir" | where-object { $_.Name -like "$file" } | %{rename-item -path $dir$_ -newname $d"_"$_}
The missing element was the %{ ... } surrounding the rename-item section which enabled me to reference $_
$d = Get-Date -format "yyyyMMddHHmm"
$dir = "C:\test"
$file = "filename*.log"
get-childitem -Path $dir | where-object { $_.Name -like $file } | %{ rename-item -LiteralPath $_.FullName -NewName "$d`_$($_.name)" }
This should work, assuming that the errors were relating to "Cannot bind argument to parameter 'Path'", and the NewName string.
Issues included:
Not being able to reference $_ when not in a foreach style block (see here)
The Concatenation issue raised by #alroc
You could, instead of passing the pipeline object to a Foreach-Object, pass directly to the Rename-Item - but I'm unsure quite how to reference the name of the object for the -NewName parameter.
I don't recall . being a string concatenation operator in PowerShell (I may be wrong). Try this:
rename-item -path $_ -newname "$d_$($_.name)"
Or this
rename-item -path $_ -newname ($d + "_" + $_.name)
Or even this
rename-item -path $_ -newname ({0}_{1} -f $d,$_.name)
See the answers here
Yet another way to do it without using foreach or %, but a script block instead:
get-childitem -Path "$dir" -filter $file | rename-item -newname { $d + "_" + $_.name }
See the examples in the doc for rename-item: https://msdn.microsoft.com/en-us/powershell/reference/3.0/microsoft.powershell.management/rename-item There's a -replace operator too, but it can't use wildcards? Oh, you don't need wildcards:
get-childitem -Path "$dir" -filter $file | rename-item -newname { $_.name -replace 'filename',($d + '_filename') }

rename file with add length (in bytes) power shell

i have a problem : in files name i have to write their lengths
for example qwerty.tmp → qwerty_12039.tmp ! please help
use:
get-childitem c:\Folder | rename-item -NewName {$_.name -replace ".tmp", $_length ".tmp"}
but it doesn't work
You left '.' there. Also: I would use BaseName instead:
ls C:\folder | Rename-Item -NewName { $_.BaseName + $_.Length + '.tmp' }

find a string in a textfile and replace it with the name of the parent folder

I have this issue where I must replace the string "121212" in all text files with the name of it's parent folder (e.g. if the parent folder is named "123456" than the string "121212" should be replaced with "123456")
I thought I figured out how to do this with the following commands:
PS E:\testenvironment> $parent=get-childitem -recurse | where {$_.FullName -match "[testenvironment]\\\d{6}$"} | foreach {$_.Name}
PS E:\testenvironment> $parent
123456
456789
654321
987654
PS E:\testenvironment> $files=get-childitem -recurse | where {$_.FullName -match "\\\d{6,6}\\AS400\\test3.txt$"} | foreach {$_.FullName}
PS E:\testenvironment> $files
E:\testenvironment\123456\AS400\test3.txt
E:\testenvironment\456789\as400\test3.txt
E:\testenvironment\654321\AS400\test3.txt
E:\testenvironment\987654\AS400\test3.txt
PS E:\testenvironment> foreach ($file in ($files)) {Get-Content "$file" | foreach-Object {$_ -replace "121212", "($name in ($parent))"} | set-content "$file"}
But I get this message :
Set-Content : The process cannot access the file 'E:\testenvironment\123456\AS400\test3.txt' **because it is being used by another process**.
At line:1 char:127
+ foreach ($file in ($files)) {Get-Content "$file" | foreach-Object {$_ -replace "121212", "($name in ($parent))"} | set-content <<<< "$file"}
+ CategoryInfo : NotSpecified: (:) [Set-Content], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand
(... i receive this for every test3.txt file ofcourse ...)
I cannot figure out how to get the "current memory" into a new variable so, that the file (that would currently be in the memory) can be overwritten with the new data.
Provided all of your text files are in the directory structure you've posted, the following will get the job done:
get-childitem $testEnvPath -recurse -filter "*.txt" | foreach{
$content = Get-Content $_.fullname
#To get the file's grandparent directory name ($_.fullname -split '\\')[-3]
$content -replace "121212", ($_.fullname -split '\\')[-3] |
set-content $_.fullname
}
Note that to 'move' to the next file / directory in memory, the enumeration of those items must be inside of the foreach statement whereas you were enumerating them outside.
Hope that helps.

Resources