I have the following documents in a folder
How do I rename them to include only the last 11 characters?
123_abcdefghijk.doc to abcdefghijk.doc
1234_abcdefghikh.doc to abcdefghikh.doc
12345_abcdefghijl.doc to abcdefghijl.doc
Thanks in advance for your help.
Not tested
#echo off
set "doc_dir=c:\docs"
setlocal enableDelayedExpansion
pushd "%doc_dir%"
for %%# in (*.doc) do (
set "docname=%%~n#"
set "docname=!docname:~-11!"
rem !!! remove the echo if ren command looks ok !!!!
echo ren "%%~f#" "%%~dp#!docname!.doc"
)
endlocal
for /f "tokens=1*delims=_" %%a in (*_*.doc) do ECHO(ren "%%a_%%b" "%%b"
(as a batch line - from the prompt reduce %% to %)
Assumed that you want to perform the task in the current directory.
Assumed that you actually want to delete the leading string up to and including the _ from the filename.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
Like #npocmaka's solution.. However..
Where you have:
echo ren "%%~f#" "%%~dp#!docname!.doc"
You need to check/re-check:
if not exist "%%~dp#!docname!.doc" ( ren "%%~f#" "%%~dp#!docname!.doc"
) else ( echo "%%~dp#!docname!.doc" already exists >> error_log.out )
Related
I am in the middle of batch extracting screenshots for contents we are planning to use on a tube site I am working on.
The jpeg files per content is labled as followed:
6c82c0239f6eb839-1
6c82c0239f6eb839-2
all the way to 120
The file name is different per content
a82384e2c46ba4af-1
a82384e2c46ba4af-2
etc.
They will all be extracted to a singe folder.
So I basically need a batch file that will create folders based on the content name without the dash and number and move all 120 jpegs in the folder with the content name.
For example:
Create folder named 6c82c0239f6eb839 and
move 6c82c0239f6eb839-1 to 6c82c0239f6eb839-120 in to the created folder.
I saw another thread with the following batch file. its pretty much what I want but the folder name is only 3 characters long and the files are copied to the newly created folders instead of moving them.
#echo off
SetLocal EnableDelayedExpansion
for /F "delims=" %%a in ('dir /b *.jpeg') do (
set Name=%%a
set Folder=!Name:~0,3!
xcopy /y "%%a" !Folder!\
)
Could someone change this so that it will display full file name without the dash and number for the folders and move files in its respective folders instead of copy?
Thank you
#echo off
setlocal
#rem Get each jpeg file.
for /F "delims=" %%A in ('2^>nul dir /b *.jpeg') do (
rem Get filename as token before the dash.
for /f "delims=-" %%B in ("%%~A") do (
rem Make dir if needed.
if not exist "%%~B" md "%%~B"
rem Check if isdir.
2>nul pushd "%%~B" && popd
if errorlevel 1 (
>&2 echo Failed isdir "%%~B".
) else (
rem Do the move operation.
>nul move /y "%%~A" "%%~B"
if errorlevel 1 (
>&2 echo Failed move "%%~A" to "%%~B"
)
)
)
)
exit /b %errorlevel%
The code is well remarked so if you want to understand
the evaluated code by changing #echo off to #echo on.
The use of %errorlevel% after the exit /b is not
required though will let you know what the errorlevel is
when #echo on is used.
The pushd tests for a directory
(even if it is a symlink).
errorlevel is checked to decide if to echo a
error message or do the move.
As the for loop variables are used direct, use of
enabledelayedexpansion is not needed.
Many commands support the argument of /? to get help
about the command. i.e. move /?.
If you only try to copy the correct jpeg to the correct folder, you can do this:
#echo off
SetLocal EnableDelayedExpansion
CD <CORRECT ROOT PATH>
for /F "delims=" %%a in ('dir /b *.jpeg') do (
set Name=%%a
REM I presume all the files have 16 characters before the dash
set Folder=!Name:~0,16!
IF NOT EXIST !Folder! MKDIR !FOLDER!
xcopy /y "%%a" !Folder!\
)
I was not able to test.
First of all, I would like to apologize for my manners regarding my initial post.
The answer by micheal_heath has resolved my issue.
Furthermore, I happened to find this post by user Salmon Trout from a different site which also worked.
Batch file to make folders with part of file name and then copy files
#echo off
setlocal enabledelayedexpansion
for %%A in (*.psd *.jpg) do (
echo file found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "tokens=1* delims=_" %%D in ("!fname!") do set folname=%%D
echo folder name !folname!
if not exist "!folname!" (
echo Folder !folname! does not exist, creating
md "!folname!"
) else (
echo Folder !folname! exists
)
echo Moving file %%A to folder !folname!
move "%%A" "!folname!"
)
echo Finished
pause
I just changed the the following line remove the hypen and numbers to create folders for the file name properly.
for /f "tokens=1* delims=-***" %%D in ("!fname!") do set folname=%%D
I still lack the knowledge on why and how both methods work, but this has been an interesting start for me. I hope other beginners trying to solve a similar issue can find something useful from this post.
I downloaded a lot of videos that are named like [site.com] filename.mp4 and I wanted to remove the prefix so that they are named like filename.mp4.
I tried a batch file with the following code:
ren "[site.com] *.mp4" "///////////*.mp4"
But the result was .com] filename.mp4 and can't rename anything beyond the dot, any ideas?
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /f "tokens=1*delims=]" %%a IN (
'dir /b /a-d "%sourcedir%\*" '
) DO IF "%%b" neq "" (
FOR /f "tokens=*" %%h IN ("%%b") DO ECHO(REN "%sourcedir%\%%a]%%b" "%%h"
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
Perform a directory scan of the source directory, in /b basic mode /a-d without directories and tokenise each filename found - the part before the first ] to %%a and the remainder to %%b.
If %%b is not empty (ie. did not contain ]) then do nothing, therwise use the default token set (which includes space) and tokens=0 to strip the leading spaces from %%b into %%h, then build the original filename and rename.
Use a for loop to split on the space in the name.
#echo off
:: Pass the file name in as an argument.
:: Split the full path into a directory and filename in case the folder has a space too
set "filepath=%~dp1"
set "filename=%~nx1"
:: Jump into the hosting directory, split the file name after the first space, and jump out
pushd %filepath%
for /f "tokens=1,*" %%A in ("%filename%") do ren "%filename%" "%%B"
popd
Just for completeness, a cmd.exe alternative:
For %A In ("*] *.*") Do #(Set "_=%A"&Call Ren "%A" "%_:*] =%")
Use parameter expansion with pattern replacement.
f='[site.com] filename.mp4'
mv "$f" "${f/\[site\.com\] /}"
Even Windows systems can execute a Bash.
http://www.mingw.org/wiki/msys
This is a for loop:
for f in *.mp4; then
mv "$f" "${f/\[site\.com\] /}"
done
#echo off
setlocal enabledelayedexpansion
for %%j in ("*") do (
set filename=%%~nj
set filename="!filename:(1)=!"
if not "!filename!" == "%%~xj" ren "%%j" "!filename!%%~xj"
)
The problem with the script is I will get a syntax error if a file has ! in its filename. What can I replace !filename! with to avoid this error?
Do the task keeping delayed expansion disabled. Furthermore, following commented .bat script respects the facts that
rename command would fail if target file already exists (otherwise, an error A duplicate file name exists, or the file cannot be found is raised), and
currently running .bat/.cmd script can't be renamed/deleted.
The script correctly handles all cmd/.bat special characters if valid in file names like ^ caret, % percent sign etc.:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "filemask=*" original file mask
rem prepare background for debugging and demonstration
pushd "D:\bat\Unusual Names"
set "filemask=0*!*.txt" narrowed file mask
for %%j in ("%filemask%") do (
if /I "%%~fj"=="%~f0" (
rem do not rename currently running script "%~f0"
rem applicable if %filemask% does not exclude %~x0 extension i.e. .bat/.cmd
rem e.g. if "%filemask%"=="*"
) else (
set "file=%%~j" name and extension
set "filename=%%~nj" name only
set "fileext=%%~xj" extension only
call :renFile
)
)
popd
ENDLOCAL
goto :eof
:renFile
set "filename=%filename:(1)=%"
if not "%filename%%fileext%"=="%file%" (
if exist "%filename%%fileext%" (
rem renaming is not possible as target file already exists
echo ??? "%file%"
) else (
rem rename command is ECHOed merely for debugging and demonstration
rem make it operational no sooner than debugged
ECHO ren "%file%" "%filename%%fileext%"
)
) else (
rem output for debugging and demonstration
echo NER "%filename%%fileext%"
)
goto :eof
Sample output:
==> dir /B "D:\bat\Unusual Names\0*!*.txt"
01exclam!ation(1).txt
02exc!lam!ation.txt
03exclam!ation!OS!(1).txt
04exc!lam!ation!OS!%OS%(1).txt
04exc!lam!ation!OS!%OS%.txt
==> D:\bat\SO\41714127.bat
ren "01exclam!ation(1).txt" "01exclam!ation.txt"
NER "02exc!lam!ation.txt"
ren "03exclam!ation!OS!(1).txt" "03exclam!ation!OS!.txt"
??? "04exc!lam!ation!OS!%OS%(1).txt"
NER "04exc!lam!ation!OS!%OS%.txt"
==>
Basically you need to toggle delayed expansion, so that the for variables are expanded when it is disabled -- like this:
#echo off
setlocal DisableDelayedExpansion
for %%j in ("*") do (
set "file=%%~j"
set "filename=%%~nj"
set "fileext=%%~xj"
setlocal EnableDelayedExpansion
set "filename=!filename:(1)=!"
if not "!filename!"=="!fileext!" (
ren "!file!" "!filename!!fileext!"
)
endlocal
)
Besides that, I corrected the quotation. Note that I did not further check the logic of your script.
I have several folders that have files with double file extensions along with regular file extensions. I need to create a batch script to search all the folders and remove the last extension with any files that have double extensions. None of the file extensions are consistent.
Here's an example
C:\test\regular.exe
C:\test\picture.jpg.doc
C:\newtest\document.doc.pdf
End Result I need
C:\test\regular.exe
C:\test\picture.jpg
C:\newtest\document.doc
#ECHO OFF
SETLOCAL
SET sourcedir=c:\sourcedir
FOR /r "%sourcedir%" %%i IN (*.*) DO (
FOR %%n IN ("%%~ni") DO IF NOT "%%~xn"=="" IF NOT EXIST "%%~dpni" ECHO REN "%%~fi" "%%~ni"
FOR %%n IN ("%%~ni") DO IF NOT "%%~xn"=="" IF EXIST "%%~dpni" ECHO CAN NOT REN "%%~fi" "%%~ni"
)
GOTO :EOF
This batch should accomplish the task.
For each file in the tree rooted at sourcedir, if the NAME of the file itself contains an 'extension' and the filename without the original extension does not exist, then rename the file. That way, if ...picture.jpg.doc is found, the rename should occur only if ...picture.jpg does not exist.
The command to rename is simply ECHOed. You'd need to remove the ECHO keyword to activate the rename - after verifying that's what you want to do.
I've added a second line to report that a rename could not be done because of an existing file.. This could be done very slightly better, but it will work.
Revised to modify name in case simple rename can not be done.
Caution - this version will rename immediately - there are no ECHOes to provide a list first because it's nonsense to provide such a list when renaming a file may produce different results on the main rename run.
#ECHO OFF
SETLOCAL
SET sourcedir=c:\sourcedir
FOR /r "%sourcedir%" %%i IN (*.*) DO (
FOR %%n IN ("%%~ni") DO IF NOT "%%~xn"=="" IF EXIST "%%~dpni" (
SET renreq=Y
FOR %%a IN (new alt extra another 1 2 3 4 5 6 7 8 9) DO IF DEFINED renreq (
IF NOT EXIST "%%~dpi%%~nn_%%a%%~xn" (
REN "%%~fi" "%%~nn_%%a%%~xn"
SET "renreq="
)
)
IF DEFINED renreq ECHO CAN NOT REN "%%~fi"
) ELSE (
REN "%%~fi" "%%~ni"
)
)
GOTO :EOF
Reasonably obviously, the list of "extras" can be extended if required.
Try this and remove the echo, if the output is OK:
#echo off &setlocal
for /r \ %%i in (*) do (
for %%j in ("%%~ni") do if "%%~xj" neq "" echo ren "%%~fi" "%%~nj"
)
Edit: added support for the entire HD.
I try to create a batch file to automaticaly rename the files contained in a folder, from this structure: A12345678.textornumbers.textornumbers.txt to a more simple one: A12345678.txt
I tried something like this:
#echo off
ECHO Renaming files
Pause
:begin
ECHO Renaming txt files
for /r %%x in (A*.*.*.txt) do (REN "%%x" A*.txt)
ECHO Renaming finished
:end
pause
done
It does not return any error, but it does nothing...
EDITED:
Ok, the problem could be seen in other way: i want to rename the file remaining the first 9 characters and the extension.
I saw a similar question here:
Deleting characters from filename
I modified and adjusted to my case to have this:
#echo off
ECHO Renaming files
Pause
:begin
REM setlocal enabledelayedexpansion (the result is the same with and without this line)
set X=9
ECHO Renaming files
for /r %%f in (*.txt) do if %%f neq %~nx0 (
set "filename=%%~nf"
set "filename=!filename:~%X%,-%X%!"
ren "%%f" "!filename!%%~xf")
ECHO Done
ECHO Processing finished
:end
pause
done
But the result is this:
Blockquote
!filename!.txt
This is for the first image in the directoy, and errors (Such file already exist) for the others.
EDITED 2:
Thanks to the replies and other information i found on internet, here is the solution i had: to remove the last characters of the filename, because i want to remain ever the first 9 characters:
#echo off
ECHO renaming files
ECHO.
Pause
:begin
set ext=QUB
set num=17
FOR /f "tokens=*" %%f in ('dir /b /a *.%ext%') do call :lab %%f
ECHO Done
pause
Exit
:lab
set original=
set original=%*
set newname=
call set newname=%%original:.%ext%=%%
call set newname=%%newname:~0,-%num%%%.%ext%
if "%newname%"==".%ext%" (goto :eof)
ren "%original%" "%newname%"
ECHO %newname%
goto :eof
This is not my code, but the solution i used from others (by Carlitos.dll). I hope it could help to others with similar problems. Thanks for your ideas and help!
The script does do something, but nothing useful - It renames each file to it's original name :-(
It all has to do with the rules for how REN works with wildcards. I had never seen any proper explanation of how REN works posted anywhere. So a few weeks ago I did extensive experiments and developed a set of rules that explain all the behavior I observed.
You can find my results at How does the Windows RENAME command interpret wildcards? on the StackExchange SuperUser site.
Your problem is easily solved by replacing * with many ? in your target name. Just make sure the number of ? is greater than or equal to the max leading name length that you will process. You also don't need to specify the leading A if you are not changing the value.
for /r %%x in (A*.*.*.txt) do ren "%%x" ?????????????????????.txt
The above must iterate each file. It may be a bit faster to iterate the folders only, though I haven't tested
for /r /d %%x in (.) do ren "%%x\A*.*.*.txt" ?????????????????????.txt
It is also possible to parse the name with FOR /F so that you don't have to worry about the number of ?.
for /r %%x in (a*.*.*.txt) do (
for /f "delims=." %%n in ("%%~nx") do ren "%%x" "%%n.txt"
)
EDIT based on revised question
To simply preserve up to the 1st 9 characters and the .txt extension, the solution is even easier, just use 9 ?:
for /r /d %%x in (.) do ren "%%x\*.txt" ?????????.txt
If you want to rename all files, not just .txt files, then
for /r %%F in (*) do ren "%%F" "?????????%%~xF"
You could also do something like this:
for %%x in (*.textornumbers.txt) do (
set nam=%%x
if "!nam!" neq "!nam:.textornumbers=!" ren %%x !nam:.textornumbers=!
)
Using ~-modifiers, you could do the following:
Take just the name from the original full path and name (& extension):
FOR /R %%A IN (A*.*.*.txt) DO (
... %%~nA ...
)
That will turn a D:\path\A*.*.*.txt to just an A*.*.*.
Take just the name from the result of #1:
FOR /R %%A IN (A*.*.*.txt) DO (
FOR %%B IN ("%%~nA") DO (
... %%~nB ...
)
)
That will leave you with A*.*.
Take just the name from #2:
FOR /R %%A IN (A*.*.*.txt) DO (
FOR %%B IN ("%%~nA") DO (
FOR %%C IN ("%%~nB") DO (
... %%~nC ...
)
)
)
which will give you A*.
Extract the extension from the original name and concatenate it with #3. That will be the final name, A*.txt, which you can now supply to the RENAME command:
FOR /R %%A IN (A*.*.*.txt) DO (
FOR %%B IN ("%%~nA") DO (
FOR %%C IN ("%%~nB") DO (
RENAME "%%A" "%%~nC%%~xA"
)
)
)