In an directory i have multiple subdirectories but some of them have square bracket in them and some characters in it. example
c:/folder/[Hello]folder1
c:/folder/fol[Hi]der2
c:/folder/[World] Folder3
The output I want is as below
c:/folder/folder1
c:/folder/folder2
c:/folder/Folder3
I have tried something as below but couldn't fix it.
for /d %%i in (*.*) do for /f "delims=][" %%j in ("%%~i") do if "%%~i" neq "%%~j" echo ren "%%~i" "%%~j"
and
#ECHO OFF
SETLOCAL EnableDelayedExpansion
FOR %%D IN ("*[*]*") do (
SET name=%%~nxD
echo "%%D"
)
You can use PowerShell's Rename-Item cmdlet with the -replace regex operator to do this:
Get-ChildItem C:\folder |Rename-Item -NewName {$_.Name -replace '\s*\[[^\[\]]+\]\s*'}
This will remove bracket pairs and their contents, as well as any whitespace surrounding them.
You can add the -WhatIf switch to verify the resulting names before executing:
Get-ChildItem C:\folder |Rename-Item -NewName {$_.Name -replace '\s*\[[^\[\]]+\]\s*'} -WhatIf
Related
I have a series of image files with a set prefix that I would like to remove. Example of the filenames that I will have:
Image_2022-06-09-12-29-00_Filename-01
Image_2022-07-09-13-29-59_Filename-02
Image_2022-02-11-09-26-31_Filename-03
I would like them to turn into:
Filename-01
Filename-02
Filename-03
I currently have a .bat file that manages to remove the first part of all the files which can either be .jpg or .png files:
set current_dir=%cd%
powershell -Command "get-childitem *.png | rename-item -newname { [string]($_.name).substring(26) }"
powershell -Command "get-childitem *.jpg | rename-item -newname { [string]($_.name).substring(26) }"
My problem now however, is that once I run this and the files are renamed, I cannot copy in new files and run the .bat file again because it will rename the files that have already been renamed. Is it possible to identify a sequence of the first part of a filename, and then apply this only to those files? The first 26 characters will always be in that format, but the numbers may change.
This simple pure Batch file should do the work (and should run much faster than the PS versions):
#echo off
for /F "delims=" %%a in ('dir /B *.png *.jpg') do for /F "tokens=3 delims=_" %%f in ("%%a") do ren %%a %%f
EDIT 2022/06/22: New method to fulfill the new specifications
#echo off
for /F "delims=" %%a in ('dir /B *.png *.jpg') do for /F "tokens=2* delims=_" %%e in ("%%a") do ren %%a %%f
Seems to me all you have to do is to split the file's BaseName (name without extension) on the underscore and take the last element. Then recombine that with the file's extension and you're good to go.
(Get-ChildItem -Path 'X:\WhereTheFilesAre' -File | Where-Object { $_.Extension -match '\.(jpg|png)' }) |
Rename-Item -NewName {'{0}{1}' -f ($_.BaseName -split '_')[-1], $_.Extension }
As per your comment, the filenames could have mixed hyphens and underscores, you can change the Rename-Item scriptblock into
Rename-Item -NewName {'{0}{1}' -f ($_.BaseName -replace '.*[-_](\w+[-_]\d+)$', '$1'), $_.Extension }
Tests:
'Image_2022-06-09-12-29-00_Filename-01' -replace '.*[-_](\w+[-_]\d+)$', '$1' # --> Filename-01
'Image_2022-07-09-13-29-59_Filename_02' -replace '.*[-_](\w+[-_]\d+)$', '$1' # --> Filename_02
As for setting the PowerShell function to use the same current directory as your batch file, please read this answer
I'd like to find all the folders under a specific path (C:\main_folder) that have no files in it.
I've found a way with cmd for doing it:
#echo off
setlocal
set "folder=C:\main_folder"
for /r "%folder%" /d %%F in (.) do dir /b "%%F" | findstr "^" >nul || (echo %%~fF) > "C:\empty_folders_list.txt"
but if I have
C:\main_folder\folder_1 containing folder_2 and no files and
C:\main_folder\folder_1\folder_2 with no files, that code gives only
C:\main_folder\folder_1\folder_2, while I'd like to have also
C:\main_folder\folder_1 in it.
It shouldn't look only to the folders that have no files, cause I can have
C:\main_folder\folder_3 containing folder_4 and no files but if
C:\main_folder\folder_3\folder_4 contains file, folder_3 and folder_4 shouldn't be listed.
And after having the list I want to delete them (the list is only for checking/saving them).
How do I write it?
Thanks!
This worked for me:
#echo off
setlocal
set "folder=C:\temp\bob"
for /r "%folder%" /d %%F in (.) do dir /b /s /a-d "%%F" 2>nul | findstr "^" >nul || echo %%~fF
output:
C:\temp>test
C:\temp\bob\empty parent
C:\temp\bob\empty parent\empty subfolder
C:\temp\bob\not empty parent\empty subfolder
If you are a supported Windows system, it will have PowerShell. This requires PowerShell 3.0+, but can be done with 2.0 with some modifications.
This gathers the list of subdirectories and sorts the names descending. This is so that an empty directory that had empty subdirectories will be removed.
When you are satisfied that the correct directories will be removed, remove the -WhatIf from the Remove-Item command.
=== Remove-Empties.ps1
$baseDir = 'C:\main_folder'
$dirs = (Get-ChildItem -Directory -Recurse -Path $baseDir).FullName | Sort-Object -Descending
foreach ($dir in $dirs) {
if (((Get-ChildItem -Directory -Path $dir).Length -eq 0) -and
((Get-ChildItem -File -Path $dir | Measure-Object).Count -eq 0)) {
"Removing directory $($dir)"
Remove-Item -Path $dir -WhatIf
}
}
=== Invoke from cmd.exe command line or .bat file script
powershell -NoLogo -NoProfile -File ".\Remove-Empties.ps1" >"C:\empty_folders_list.txt"
I would like to delete all the files located in folders named \log\ . This folder can be everywhere (at any levels) in sub directories
ideally i want to do something like
del c:\myapp\*\log\* /s /q
how can i do this ?
A single line example from the Command Line, cmd.exe:
For /F "Delims=" %A In ('Dir /B/S/AD "C:\myapp\log" 2^>Nul') Do #Del /A/F/S/Q "%A\*"
If you want it inside a batch file, *.cmd|*.bat:
#For /F "Delims=" %%A In ('Dir /B/S/AD "C:\myapp\log" 2^>Nul') Do #Del /A/F/S/Q "%%A\*"
Here is a command that can be used in a .bat file script. When you are confident that the correct files will be deleted, remove the -WhatIf from the Remove-Item cmdlet.
powershell -NoProfile -Command ^
"Get-ChildItem -Directory -Recurse -Filter 'log' | " ^
"ForEach-Object { Get-ChildItem -File -Path $_.PSPath | Remove-Item -WhatIf }"
Yes, it can be sorter and more cryptic and more expensive to maintain. Almost as much fun as a .bat FOR loop.
powershell -NoProfile -Command "gci -di -rec -filt 't' | %% { gci -file $_.PSPath | ri -WhatIf }"
I need to rename a whole file structure, and find a certain piece of string such as "_foo" and rename it to "". The structure will be like :
something_foo->multiples_folders_and_files_foo->multiples_folders_and_files_foo->files_foo
Where all the files in each folders and each folders in each folders must not contain the piece fo string "_foo".
I am working under windows. I have tried powershell script, I was able to rename a single folder, but not recursivly rename all folders.
thanks guys!
#echo off
setlocal
set "string_to_remove=_foo"
set "root_dir=c:\root"
pushd "%root_dir%"
setlocal enableDelayedExpansion
for %%f in (*) do (
set "file_name=%%f"
ren "!file_name!" "!file_name:%string_to_remove%=!"
)
for /r /d %%# in (*) do (
set "dir_name=%%#"
pushd "%%#"
for %%f in (*) do (
set "file_name=%%f"
ren "!file_name!" "!file_name:%string_to_remove%=!"
)
popd
if "!dir_name!" NEQ "!dir_name:%string_to_remove%=!" move "!dir_name!" "!dir_name:%string_to_remove%=!"
)
popd
endlocal
Not tested but try this (in PowerShell)
PS> ls -rec -path $path | Ren -new { $_.name -replace '_foo' } -passthru
If work remove -passthru switch
Edit:
If '_foo' in the end of the name you can change the expression like:
| Ren -new { $_.basename -replace '_foo$' } -ea silentlycontinue
Edit:
For more robust code: (thank TheMadTechnician)
PS> GCI $path -filter '*_foo*' -rec | Ren -new { $_.name -replace '_foo' } -passthru
#echo off
setlocal enableextensions disabledelayedexpansion
set "remove=_foo"
for /f "delims=" %%a in ('dir /s /b "*%remove%*.*" 2^>nul ^| sort /r') do (
set "name=%%~nxa"
setlocal enabledelayedexpansion
for %%b in ("!name:%remove%=!") do endlocal & echo ren "%%~fa" "%%~b"
)
This will enumerate all matching files/folders, sort in reverse order (so files are processed before the folders that contains them) and for each one, remove the indicated string
Rename operations are only echoed to console. If the output is correct, remove the echo command
I need to rename various files in different folders. There is a prefix 'f_' in all the filenames that need to be removed.
I managed to do this using the following lines in Powershell.
cd "C:\Users\pieter\Desktop\Folder1\Folder2\20140402_Export"
Get -ChildItem -filter "*f_*" -recurse | Rename-item -newname { $_.name -replace "f_","" }
This works, but how do I make a .bat out of this?
I would like to doubleclick a script file that automatically does the same job.
Thanks!
Create a batch file and the following there, it will execute your command in Powershell thread and exit.
#powershell "cd 'C:\Users\pieter\Desktop\Folder1\Folder2\20140402_Export'; Get-ChildItem -filter "*f_" -recurse | Rename-item -newname { $_.name -replace 'f_','' }"
try this:
#cd /d "C:\Users\pieter\Desktop\Folder1\Folder2\20140402_Export"
for /f "delims=" %%a in ('dir /b /a-d /s "*f_*"') do (
set "name=%%~na"
setlocal enabledelayedexpansion
set "new=!name:f_=!"
ren "%%a" "!new!%%~xa"
endlocal
)