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"
)
)
)
Related
I have created a batch file which should do several things, including appending all text documents of a certain format into one text file provided there are more than one text files of this format in the directory. This section of the code is below:
:multiple
SET /a count=0
ECHO.> "%location%\UAV_camera_coords_all.txt"
FOR /r "%location%\Output" %%G in ("UAV_camera_coords_*.txt") do set /a count+=1
IF %count% GTR 1 (
FOR /r "%location%\Output" %%G in ("*.txt") DO (
SET file=%%~G
TYPE "%file%">>"%location%\UAV_camera_coords_all"
)
GOTO :end
It seems that the code is crashing upon reaching the if statement even though the count variable is greater than one. None of the code in the if statement is executed and indeed none of the code which should come after the if statement is executed either. Is there any syntax or other error which may be causing this?
Besides my comment. I assume that you are not really planning on typing the output of *.txt but instead only UAV_camera_coords_*.txt.. if not, feel free to change it back to *.txt
#echo off
for /f "tokens=1,*" %%i in ('dir /s "%location%\UAV_camera_coords_*.txt" ^| findstr "File(s)"') do set cnt=%%i
if %cnt% gtr 1 (
for /f %%a in ('dir /b /s "%location%\UAV_camera_coords_*.txt"') do type "%%~a"
)>"%location%\UAV_camera_coords-all.txt"
Note, I changed the output filename to be -all and not _all as that would type the file onto itself if it was to be a txt file as well.
Edit adding back original answer, before I realised you were recursively searching through directories:
#echo off
for /f "tokens=1,*" %%i in ('dir "UAV_camera_coords_*.txt" ^| findstr "File(s)"') do if %%i gtr 1 type "UAV_camera_coords_*.txt">>"%location%\UAV_camera_coords_all"
Just for the purpose of providing an alternative, this one uses xcopy to check the file count, and copy to merge them.
PushD "%location%\Output" 2>NUL && For /F %%G In ('""%__AppDir__%xcopy.exe" "UAV_camera_coords_*.txt" . /SQL"')Do If %%G Gtr 1 Copy /Y /B "UAV_camera_coords_*.txt" "..\UAV_camera_coords_all.txt">NUL & PopD
Trying to create a script that will take the third token of a file name, create a folder based on it and move the associated file to that folder.
Have got this so far:
#ECHO OFF
SETLOCAL
SET "sourcedir=D:\Sourcedir"
PUSHD %sourcedir%
FOR /f "tokens=1,2,3,4 delims=" %%a IN (
'dir /b /a-d "*.pdf"'
) DO (
ECHO MD %%c
ECHO MOVE "%%a %%b %%c %%d" .\%%c\
)
POPD
GOTO :EOF
Only problem is the folder being created is including the file extension where as I just need the folder to be named the third token.
Example file name:
"File Number 10.pdf
Expected folder name:
10
Thanks
Why did you use delims=? This will remove delimiter, and take whole line to %%a.
Try this:
#ECHO OFF
SETLOCAL
SET "sourcedir=D:\Sourcedir"
PUSHD %sourcedir%
FOR /f "tokens=1,2,3" %%a IN (
'dir /b /a-d "*.pdf"'
) DO (
ECHO MD %%~nc
ECHO MOVE "%%a %%b %%c" .\%%~nc\
)
POPD
GOTO :EOF
When no delims= set, it will use space. So %%c will be 10.pdf, ~n is to extract its name part.
This is based on your question, which you can concatenate %%a %%b %%c together with spaces, then it's simple.
If your filenames are more complicated, then an inner for loop is better.
-- Which another question already gave a great solution.
Here's an alternative, which will just use the last space delimited string/number, regardless of how many there are, (if there are none it will use the whole filename)!
#Echo Off
For %%A In ("D:\Sourcedir\*.pdf") Do Call :L "%%A"
Exit /B
:L
Set "F=%~n1"
Set "F=%F: ="&Set "F=%"
If Not Exist "%~dp1%F%\" MD "%~dp1%F%"
Move /Y %1 "%~dp1%F%"
And if you wanted to move only those which have at least one space, you can include that inside the For parentheses.
#Echo Off
For %%A In ("D:\Sourcedir\* *.pdf") Do Call :L "%%A"
Exit /B
:L
Set "F=%~n1"
Set "F=%F: ="&Set "F=%"
If Not Exist "%~dp1%F%\" MD "%~dp1%F%"
Move /Y %1 "%~dp1%F%"
You can run 2 for loops get the full name in the first, then split the name in the second loop, get the 3rd token, create the directory and then copy the actual file name from the first loop.
This way you do not need to try and patch the name together again, I know it works, but it is ugly and not prefered:
#echo off
setlocal enabledelayedexpansion
set "sourcedir=D:\Sourcedir"
pushd %sourcedir%
for %%a in (*.pdf) do (
set "var=%%a"
for /f "tokens=3" %%i in ("!var!") do (
echo md "%%~ni"
echo move "%%~a" "%%~ni"
)
)
popd
goto EOF
For more information on these commands, see help for each from cmd.exe i.e
for /?
set /?
setlocal /?
set and setlocal has very specific information regarding delayed expansion.
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 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 )
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.