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
Related
I need a bat to delete all files with the RELATIVE name that are NOT contained in a text file
In the text file list.txt i have this:
C:\S-ATLANTICO-1\MEDIA\Innplay-Logo.mp4
C:\S-ATLANTICO-1\MEDIA\logo-FB_sep.png
C:\S-ATLANTICO-1\MEDIA\logo-news_sa.png
and the in the same folder have this files:
Innplay-Logo.mp4
logo-FB_sep.png
logo-news_sa.png
Carlos.jpg
Sapo.png
list.txt
So i need to delete the next files because not exist in list.txt
Carlos.jpg
Sapo.png
but i also MUST KEEP the LIST.TXT
i have tried this but without sucess
#echo off
setlocal
set "folder=C:\S-ATLANTICO-1\MEDIA"
set "excludeFile=C:\S-ATLANTICO-1\MEDIA\list.txt"
for /f "eol=: delims=" %%F in ('dir /b /a-d "%folder%" ^| findstr /vig:"%excludeFile%" ^| findstr /v /i "\list.txt"') do del "%folder%\%%F"
any one can help me with this.
Thanks
Give this a shot. It works for my testing.
I have placed echo statements instead of actually deleting anything.
#echo off
setlocal
set "folder=C:\S-ATLANTICO-1\MEDIA"
set "excludeFile=%folder%\list.txt"
:: Check that both the target folder and filter file exist before starting up.
if not exist "%folder%" echo %~nx0: The target folder doesn't exist. Nothing to do.&& goto :EOF
if not exist "%excludeFile%" echo %~nx0: The list file doesn't exist at the location specified!&& goto :EOF
for /f "delims=" %%F in ('dir /b /a-d "%folder%"') do call :process_file "%%F" "%~0" "%excludeFile%"
goto :EOF
:: --------------------------------------------
:process_file
:: --------------------------------------------
set input_file=%~1
set this_batch=%~2
set list_file=%~nx3
:: Skip list file and this batch file too
if "%this_batch%"=="%input_file%" echo Skip this batch file&& goto :EOF
if "%list_file%"=="%input_file%" echo Skip list file&& goto :EOF
:: Grep for the include file in the list
findstr /C:"%input_file%" "%excludeFile%" 2>&1 1>NUL
:: Bail out if the input line was in the list file
if not errorlevel 1 echo Skip "%input_file%", it is in %list_file%&& goto :EOF
:: Delete anything left
echo delete file %input_file%&& goto :EOF
goto :EOF
Give this a try. It iterates over the contents of $thedir and deletes files that are not in list.txt and are not scripts. Put these two (2) files in the same directory. It would be best not to put them in the same directory as the files being deleted. Run the .bat file from a cmd.exe shell.
When you are satisfied that the correct files will be removed, remove the -WhatIf from the Remove-Item cmdlet.
=== Remove-Except.ps1
$thedir = 'C:\src\t\delexcept'
$precious = (Get-Content -Path (Join-Path -Path $thedir -ChildPath 'list.txt')) +
#(Join-Path -Path $thedir -ChildPath 'list.txt')
Get-ChildItem -Path $thedir -Exclude 'list.txt','*.ps1','*.bat' |
Where-Object { (-not $_.PSIsContainer) -and
($precious -notcontains $_.FullName) -and
$_.FullName.StartsWith($thedir) } |
ForEach-Object { Remove-Item -Path $_.FullName -WhatIf }
=== Remove-Except.bat
powershell -NoLogo -NoProfile -File "%~dpn0.ps1"
On cmd line this should do
for /f "delims=" %A in ('Dir /B /A-D ^|find /v /i "list.txt"') Do #findstr /IL "%~nxA" list.txt >Nul ||(echo del %A)
I'd include the /E switch with findstr if the last line in list.txt has a trailing cr/lf,
otherwise the last entry wouldn't match reference.
If the output looks OK, remove the echo in front of del.
As a batch file:
#Echo off
set "folder=C:\S-ATLANTICO-1\MEDIA"
PushD "%folder%"
set "excludeFile=list.txt"
for /f "delims=" %%A in ('
Dir /B /A-D ^|find /v /i "%excludefile%"'
) Do findstr /IL "%~nxA" "%excludefile%" >Nul ||(
echo del %%A
)
Popd
I have files such as:
How can I replace example to test-file in each of them?
I want solutions for:
Batch file
PowerShell
Bash
This is a batch-file solution:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%A IN ('dir /B /A-D "example*"') do (
set "fname=%%~nA"
rename "%%~fA" "!fname:example=test-file!%%~xA"
)
which should work. If you don't want to hardcode the word to replace, use:
#echo off
setlocal EnableDelayedExpansion
set "word=test-file"
for /F "delims=" %%A IN ('dir /B /A-D "example*"') do (
set "fname=%%~nA"
rename "%%~fA" "!fname:example=%word%!%%~xA"
)
For cmd one-line use:
for /F "delims=" %A IN ('dir /b /a-d "example*"') do #set "fname=%~nA"&call rename "%~fA" "%fname:example=test-file%%~xA"
Here's a batch-file solution:
#For %%A In (example*)Do #Set "_=%%A"&Call Ren "%%A" "test-file%%_:*example=%%"
As one has not yet been submitted, here's a powershell answer:
Get-ChildItem -Filter 'example*' | Rename-Item -NewName {$_.Name -Replace '^example','test-file'}
You could of course utilise PowerShell from a batch-file:
#Powershell -NoP "GCI -Filt 'example*'|RnI -N {$_.Name -Replace '^example','test-file'}"
For a bash solution, you're going to need to be more specific, because different OS'es/distributions etc. use different methods, some may use rename from util-Linux others may use the Perl rename utility. Others may not have rename and need to utilise a for loop with the mv command.
for f in example*; do mv "$f" "${f/example/test-file}"
[Edit /]
To run a command from the Command Prompt despite your lack of a cmd tag:
For %A In (example*)Do #Set "_=%A"&Call Ren "%A" "test-file%_:*example=%"
In bash you can use rename command like this:
rename example test-file example*
Here first argument is required expression to be changed, second argument is replacement and last argument is file name
I used the below code in .bat file in order to delete all files and folders inside “AutoCAD_Temp” except “parcel.dwg” but it didn’t work with me.
#echo
set exclude=/Parcel.dwg/
for %%a in (C:\inetpub\Temp_FME\AutoCAD_Temp) do (
if "!exclude:/%%~a/=!" equ "%exclude%"
(
echo "Deleting" %%~a
del "%%~a"
)
)
The folder Path: C:\inetpub\Temp_FME\AutoCAD_Temp
enter image description here
What might be the issue here?
I will be very appreciated for any help,
Lubna
If there is only one file to protect, all you need to do is to lock it
#echo off
setlocal enableextensions disabledelayedexpansion
rem Just to avoid having to retype paths, place info on variables
set "folder=C:\inetpub\Temp_FME\AutoCAD_Temp"
set "excluded=Parcel.dwg"
rem If the excluded file exist, we will need to lock it.
if exist "%folder%\%excluded%" ( set lock= ^< "%excluded%" ) else ( set "lock=" )
rem Change to requested folder, remove anything not locked and return
pushd "%folder%" && (
rmdir . /s /q %lock% 2>nul
popd
)
The reason for the file existence check is to avoid trying to lock a non existing file that will make the command fail, so, lock variable (holding the part of the final command that will lock the file for reading) is only defined if the file exists.
This is one line in PowerShell, for your consideration:
Get-ChildItem C:\inetpub\Temp_FME\AutoCAD_Temp\* -File -Exclude Parcel.dwg | Remove-Item -WhatIf
(If the output is correct, remove the -WhatIf parameter to remove the files.)
use findstr to exclude the file from the search using /v
#echo off
for /f "delims=" %a in ('dir /b "C:\inetpub\Temp_FME\AutoCAD_Temp" ^| findstr /vi "Parcel.dwg"') do (
echo "Deleting" %%~a
echo del "%%~a"
)
if you would like to predefine variables, simply:
#echo off
set "mypath=C:\inetpub\Temp_FME\AutoCAD_Temp"
set "exclude=Parcel.dwg"
for /f "delims=" %a in ('dir /b "%mypath%" ^| findstr /vi "%exclude%"') do (
echo "Deleting" %%~a
echo del "%%~a"
)
i have a folder and it contains hundreds of text file, i want to rename it .
file names ABCD01%%.txt or CAT9999&#.txt OR FILENAME2345&^$.txt
i want to rename file such that anything that comes between 'numbers' and '.txt' should be removed
for example
ABCD01%%.txt becomes ABCD01.txt
CAT9999&#.txt becomes CAT9999.txt
FILENAME2345&^$.txt becomes FILENAME2345.txt
Code so far:
#echo off
for /f "tokens=*" %%f in ('dir /l /a-d /b *.txt') do (
for /f "tokens=1 delims=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" %%n in ("%%~nf") do (
echo File: %%~nxf = value %%n
rename %%~nxf *%%n.txt
)
)
Another solution i get for linux is rename 's/[^a-zA-Z0-9_]//g' *.txt , i tried to port it for windows but i cant .. how can the above command be ported to windows (batch)
Assuming there are no duplicate renames and assuming that only letters and numbers make up the first part of the filename, the following code will rename the files. When you are satisfied that the renaming is being done correctly, remove the -WhatIf from the Rename-Item command.
Get-ChildItem -File -Filter '*.txt' |
Where-Object { $_.Name -match '([A-Za-z0-9]*).*\.txt' } |
ForEach-Object { Rename-Item $_.FullName "$($matches[1]).txt" -WhatIf }
If you are not running in PowerShell, put the code into a renfunc.ps1 file and invoke it from the cmd .bat script.
powershell -NoProfile -File 'renfunc.ps1'
I've encountered a few problems with escaping characters, I had to use a slightly different method. This script should work:
setlocal enabledelayedexpansion
for %%f in (*.txt) do (
set name=%%~nf
for /f "delims=0123456789 tokens=2" %%r in ("%%~nf") do set replace=%%r
set "replace=name:!replace:^^=!="
for /f %%x in ("!replace!") do set replace=!%%x!
ren "!name!.txt" "!replace!.txt"
)
EDIT: This revised script looks for the last numbers in the file name. [Don't mind the errors, they don't have any effect on the actual renaming.]
setlocal enabledelayedexpansion
for %%f in (*.txt) do (
set name=%%~nf
set p=0
for /l %%# in (2 1 32) do (
for %%e in ("!name:~-%%#,1!") do (
echo.%%~e|findstr /r /i "[0-9]"&&if !p!==0 set /a p=%%#-1
)
)
set "new=name:~,-!p!"
for %%e in ("!name:~-1!") do echo.%%~e|findstr /r /i "^[0-9]"&&set new=name
for /f %%x in ("!new!") do ren "!name!.txt" "!%%~x!.txt"
)
EDIT: Revised again for the special case of "&&". Delayed expansion within a for-loop can be tedious. Now the characters won't break syntax anymore (which means the errors that were to be ignored have ceased).
I'm a newbie at this but have spent the afternoon searching your forums. While there are several posts about the ren command i can't seem to get mine to work?!
I would like to change:
A22-7000
A22-7001
A22-7003
to:
A24-7000
A24-7001
A22-7003
I opened the cmd window in the folder location and tried various forms of the following:
ren *A22 *A24
I know this should be easy but it's been driving me insane! Also, if anyone has a link to good tutorials where I can learn this sort of this that would be great!
Thanks!
you got the concept of wildcards wrong.
*A22 means "anything that ends with A22"
* means "any count of characters"
? means "one character"
What you want is probably:
ren A22* A24*
A22* means "anything that starts with A22 followed by any number of chars"
first you should certain you want change folder or file name when you use just ren that rename all find with your wild card !
see my example
if you have A22-7000 file and folder when you ren A22* A24* you change all folder and file if you want change
just folder
random.bat
dir /A:D /b | findstr.exe /n /R "a*" > s:\sites\file-count.txt
FOR /F "tokens=1-10 delims=:" %%A IN ('type "s:\sites\file-count.txt"') do set NUMBER-OF-FILES=%%A
FOR /L %%A IN (1,1,%number-of-files%) DO CALL rename.bat %%A
rename.bat
:rename
FOR /F "tokens=1-10 delims=:" %%A IN ('type "s:\sites\file-count.txt" ^|
findstr "%1:"') do ren %%B a24-%RANDOM%
just file :
random.bat
dir /A:-D /b | findstr.exe /n /R "a*" > s:\sites\file-count.txt
FOR /F "tokens=1-10 delims=:" %%A IN ('type "s:\sites\file-count.txt"') do set NUMBER-OF-FILES=%%A
FOR /L %%A IN (1,1,%number-of-files%) DO CALL rename.bat %%A
rename.bat:
FOR /F "tokens=1-10 delims=:" %%A IN ('type "s:\sites\file-count.txt" ^|
findstr "%1:"') do ren %%B a24-%RANDOM%
also you can do this with powershell script like
just for folder
gci -Directory -Filter A22* | foreach { Rename-Item $_.Name -NewName A24* }
just for file
gci -file -Filter A22* | foreach { Rename-Item $_.Name -NewName A24* }