On Windows XP, in a folder of files, I need to rename some files, replacing one character in the filename with another and overwriting any files that already have that name.
For example, the folder contains these 2 files:
fileA.xml
fileb.xml
I need to rename fileA.xml to fileb.xml, overwriting the original fileb.xml
Using PowerShell, I have this command:
Get-ChildItem *.* -include *.xml | Rename-Item -NewName { $_.name.Replace("A","b")}
The rename doesn't work as the file already exists.
Doesn't have to be done in PowerShell, but this is the closest I've come so far.
You can try the Move-Item command instead, with the -Force parameter.
Get-ChildItem . -include *.xml | Move-Item -Destination { $_.name.Replace("A","b")} -Force
First, you need to filter to get the files that you actually want to rename.
Get-ChildItem . -include *.xml | Where-Object { $_.name -match "A$" }
And feed this to Move-Item to rename:
Get-ChildItem . -include *.xml | Where-Object { $_.name -match "A$" } | Move-Item -destination { $_.name -replace "A$", "b" }
Related
I'm trying to use powershell to copy some directories where name match with filter.
First of all I delete all the directories that match in the destination path, alfter I try to copy source directories and contents but I've a problem because are copied only files inside directories and subdirectories and not the directories names and structures.
$source="F:\origin"
$destination="F:\dest"
$filter="#"
# Remove dirs #
Get-ChildItem -Path $destination -Recurse |
Where-Object { $_.DirectoryName -match $filter } |
remove-item -Recurse
# Copy dirs and all contents
Get-ChildItem -Path $source -Recurse |
Where-Object { $_.DirectoryName -match $filter } |
Copy-Item -Destination $destination
How can I do This ?
Thank you
EDIT
F:\origin\#test\index.php
F:\origin\#test1\index1.php
F:\origin\#test1\sub1\subindex1.php
F:\origin\no_consider\index1.php
Expected output
F:\dest\#test\index.php
F:\dest\#test1\index1.php
F:\dest\#test1\sub1\subindex1.php
a couple small tweaks seems to have done the trick. replaced some double quotes with single quotes, added a Recurse at the end of the one line and change DirectoryName to Name for the first one.
LEt me know if this works:
$source='c:\origin'
$destination='c:\dest'
$filter="#"
# Remove dirs #
Get-ChildItem -Path $destination -Recurse |
Where-Object { $_.Name -match $filter } |
remove-item -Recurse
# Copy dirs and all contents
Get-ChildItem -Path $source |
Where-Object { $_.Name -match $filter } |
Copy-Item -Destination $destination -Recurse -Force
I'm new in powershell, I have to execute the following statement recursively:
Get-ChildItem | ForEach-Object {Rename-Item $_ -NewName ("new_filename{0}.smali" -f $nr++)}
In other words I have to rename all the .smali files in the subdirectories with any other name different from the current one (keeping the .smali extension).
Get-ChildItem -Path FolderPath -Filter *.smali -Recurse | ForEach-Object{$_ | Rename-Item -NewName ($.BaseName + StringToAdd + $.Extension) -WhatIf}
Copy the above line as is... Replace the values for FolderPath and StringToAdd and give it a try. If everything looks fine then execute it by removing the -Whatif switch.
dir is an alias for Get-ChildItem which has a -Recursive parameter.
$nr = 0; Get-ChildItem -Recurse -Filter "*.smali" | Rename-Item -NewName "new_filename$($nr++).smali"
Things to note:
DIR is an alias for Get-ChildItem. Get-ChildItem is more Powershell-y
Your command only looked at the top level directory, so I added the -recurse
Your command would rename all files, not just the "*.smali", so I added the filter.
Im still generally new to powershell, and I am trying to create a program that will take files based on their name, and move them into folders that have a similar name but not exactly the same.
For example, Lets say I have 3 files, Apples.txt, Grapes.txt, and Oranges.txt. And I want to move them into corresponding folders, ApplesUSA, GrapesNY, OrangesFL.
I could just hard code it using a loop and a If-Then Statement. i.e If Apples.txt exists move to ApplesUSA. But I want it to be dynamic, so if other files and folders are added later I dont have to update the code. Is there a way to write a statement that would say if FileA and FolderB are similar in name (both contain apples in the name somewhere) then move fileA to FolderB and so on.
Any help appreciated. Thanks!!!!
try Something like this
$PathWithFile="C:\temp\Test"
$PathWithDir="C:\temp\Test"
Get-ChildItem $PathWithFile -file -Filter "*.txt" | %{
$CurrentFile=$_
$Dirfounded=Get-ChildItem $PathWithDir -Directory | where {$_ -match $CurrentFile.BaseName} | select FullName -First 1
if ($Dirfounded -ne $null)
{
move-Item $CurrentFile.FullName -Destination $Dirfounded.FullName -WhatIf
}
}
A oneliner similar to #Esperento's
gci *.txt -af|%{$File=$_.FullName;gci "$($_.BaseName)*" -ad|%{Move $File -Dest $($_.FullName) -whatif}}
The verbose version:
PushD "X:\path\to\base\folder"
Get-ChildItem *.txt -File | ForEach-Object{
$File = $_.FullName
Get-ChildItem "$($_.BaseName)*" -Directory | ForEach-Object {
Move-Item $File -Destination $_.FullName -whatif
}
}
PopD
Both versions require PowerShell V3 for the -File and -Directory parameters (and their aliases -af/-ad) This can be substituted by an additional |Where-Object{ $_.PSIsContainer} respective | Where-Object{!$_.PSIsContainer}
I have a piece of software which looks for a files named "report.txt". However, the text files aren't all named report.txt and I have hundreds of sub folders to go through.
Scenario:
J:\Logs
26-09-16\log.txt
27-09-16\report270916.txt
28-09-16\report902916.txt
I want to search through all the sub folders for the files *.txt in J:\logs and rename them to report.txt.
I tried this but it complained about the path:
Get-ChildItem * |
Where-Object { !$_.PSIsContainer } |
Rename-Item -NewName { $_.name -replace '_$.txt ','report.txt' }
Get-ChildItem * will get your current path, so in instead let's use the define the path you want Get-ChildItem -Path "J:\Logs" and add recurse because we want the files in all the subfolders.
Then let's add use the include and file parameter of Get-ChildItem rather than Where-Object
Then if we pipe that to ForEach, we can use the Rename-Item on each object, where the object to rename will be $_ and the NewName will be report.txt.
Get-ChildItem -Path "J:\Logs" -include "*.txt" -file -recurse | ForEach {Rename-Item -Path $_ -NewName "report.txt"}
We can trim this down a bit in one-liner fashion with a couple aliases and rely on position rather than listing each parameter
gci "J:\Logs" -include "*.txt" -file -recurse | % {ren $_ "report.txt"}
To replace certin word in all files in all sub folders
Get-ChildItem C:\Path -Recurse -Filter *OldWord* | Rename-Item -NewName { $_.name -replace 'OldWord', 'NewWord'} -verbose
I have a bunch of html files that I need to rename with url encoding before I upload them to the server. I've tried:
Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html | Rename-Item -NewName { $_.Name.replace("*.html",[Web.Httputility]::UrlEncode("*.html")) }
But that doesn't apply the encoding, can this be even done somehow?
Here's a basic way to do it, based on this answer:
(Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html -File) |
foreach { ren $_.fullname ([uri]::EscapeDataString($_))}
Originally I had written it without the () around the Get-ChildItem, but found it was still reading directory information while the rename had already renamed the first item. Then the rename reencoded the first item a second time, thus making it a bit munged up.
Here's a cleaner version that handles the files first and then folders:
$files = Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html -File
$folders = Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html -Directory
$files | foreach { ren $_.fullname ([uri]::EscapeDataString($_))}
$folders | foreach { ren $_.fullname ([uri]::EscapeDataString($_))}
Based on your answers i did this to make it work
(Get-ChildItem -Path c:\temp\ -Recurse -Filter *.html) |
foreach { ren $_.fullName ([uri]::EscapeDataString($_.Name))} | Out-Null
Get-ChildItem -Path c:\temp\ -Recurse | ?{ $_.PSIsContainer } |
foreach { ren $_.fullName ([uri]::EscapeDataString($_.Name))}
First I had to do only files and then folders, because when top folder gets renamed, then the path to files inside it doesn't exist any more.