Batch file that renames files numerically not working - batch-file

I have a folder into which I do a print to file option and it saves my print job as a pcl file. The software I use to do the print to file names each file in following manner: GUID.XX.pcl where XX is a number.
Example:
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.7.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.8.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.9.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.11.pcl
What I want to do is rename the files so that they look like this:
1.pcl
2.pcl
3.pcl
and so on.
Here is the batch I use:
for %%a in (*.pcl) do (
set /a i+=1
ren "%%a" "!i!.new"
)
ren *.new *.pcl
This works but the problem is,in the example I gave above
It renames
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl to 1.pcl
and
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl to 3.pcl
I need it to rename
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl to 1.pcl
and
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl to 5.pcl
It is basically seeing 10 before 6. Is there some way around this?

for /F "tokens=1-3 delims=." %%a in ('dir /B *.pcl') do (
set /A num=100+%%b
set "name[!num:~1!]=%%a.%%b.%%c"
)
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i!.pcl"
)
If you want to use two digits in the new name, so the order be preserved in dir or for listings, modify the second part this way:
set i=100
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i:~1!.pcl"
)
EDIT: I tested my code and it works correctly. This is the output of the test session:
C:\> dir /b
test.bat
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.10.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.11.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.6.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.7.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.8.pcl
{2E594442-FDF9-4992-88DA-EA4ED2811ECD}.9.pcl
C:\> test
C:\> dir /b
1.pcl
2.pcl
3.pcl
4.pcl
5.pcl
6.pcl
test.bat
C:\> type test.bat
#echo off
setlocal EnableDelayedExpansion
for /F "tokens=1-3 delims=." %%a in ('dir /B *.pcl') do (
set /A num=100+%%b
set "name[!num:~1!]=%%a.%%b.%%c"
)
for /F "tokens=2 delims==" %%a in ('set name[') do (
set /A i+=1
ren "%%a" "!i!.pcl"
)

not tested:
for %%a in (*.pcl) do (
for /f "tokens=2 delims=}" %%# in ("%%~nxa") do (
ren "%%~fa" "%%#"
)
)

Related

I can't get a variable of loop

I am trying to write a simple batch file
The script gets namefile for the file "dump" and I split the string, but i can't display the variable !!
for /r %%a in (dump\*) do (
set file=%%a
for /f %%i in ("%%a") do (
for /F "tokens=1 delims=-" %%d IN ("%%~ni") do set db=%%d
)
echo %db%
)
pause
Any ideas?
Thanks for your help.
try setting the setlocal ENABLEDELAYEDEXPANSION and swapping the var with exclamation marks instead, see below:
setlocal ENABLEDELAYEDEXPANSION
for /r %%a in (dump\*) do (
set file=%%a
for /f %%i in ("%%a") do (
for /F "tokens=1 delims=-" %%d IN ("%%~ni") do set db=%%d
)
echo !db!
)
pause

changing directory folder to all sub folders

Hello i have a batch script but i cant work out how to change the path to scan all subfolders within the directory.
In other words i dont want -
C:\Users\ally\Desktop\Documents\Table\CSV versions\2014\
but rather:
C:\Users\ally\Desktop\Documents\Table\CSV versions
as there are lots of different years of data in seperate folders.
Also to note within year folder there are month folders and within that there are the csv files.
#echo off
setlocal enabledelayedexpansion
set "target=C:\Users\ally\Desktop\Documents\All"
cd /d "C:\Users\ally\Desktop\Documents\Table\CSV versions\2014\"
for /L %%a in (101,1,148) do (
set num=%%a
del "%target%\-!num:~-2!.csv" 2>nul
>"%target%\-!num:~-2!.csv.txt" echo Type,angle,edge,Date,Frame,Sum,Mafe,Comp,Rim,Dose,Ell,Role
)
for %%a in (*.csv) do (
for /f "skip=1 usebackq delims=" %%b in ("%%a") do (
for /f "tokens=1,2 delims=-," %%c in ("%%b") do (
set "line=%%c"
if /i "!line:~0,2!"=="HH" >> "%target%\-%%d.csv.txt" echo %%b
)
)
)
ren "%target%\*.csv.txt" *.
pause
To process every folder under the All tree then you can use a for /d /r loop and pushd/popd to set the current folder.
This assumes that every folder has the files you want to process.
Test this on a copy of your data and change the folder to point to it.
You seem to be deleting .csv files, creating .csv.txt files and then trying to process *.csv in the lower loop. Should that be *.csv.txt ?
#echo off
setlocal enabledelayedexpansion
for /d /r "c:\Users\ally\Desktop\Documents\All" %%z in (*) do (
pushd "%%z"
for /L %%a in (101,1,148) do (
set num=%%a
del "-!num:~-2!.csv" 2>nul
>"-!num:~-2!.csv.txt" echo Type,angle,edge,Date,Frame,Sum,Mafe,Comp,Rim,Dose,Ell,Role
)
for %%a in (*.csv) do (
for /f "skip=1 usebackq delims=" %%b in ("%%a") do (
for /f "tokens=1,2 delims=-," %%c in ("%%b") do (
set "line=%%c"
if /i "!line:~0,2!"=="HH" >> "-%%d.csv.txt" echo %%b
)
)
)
ren "*.csv.txt" *.
popd
)
pause
Try adding another loop that will walk down the directory tree and if it finds a csv file, it will process it:
#echo off
setlocal enabledelayedexpansion
set "target=C:\Users\ally\Desktop\Documents\All"
for /f "tokens=1* delims=" %%D in ('dir /s /b /o:-n /a:d "C:\Users\ally\Desktop\Documents\Table\CSV versions"') do (
cd /d "%%~fD"
if exist *.csv (
for /L %%a in (101,1,148) do (
set num=%%a
del "%target%\-!num:~-2!.csv" 2>nul
>"%target%\-!num:~-2!.csv.txt" echo Type,angle,edge,Date,Frame,Sum,Mafe,Comp,Rim,Dose,Ell,Role
)
for %%a in (*.csv) do (
for /f "skip=1 usebackq delims=" %%b in ("%%a") do (
for /f "tokens=1,2 delims=-," %%c in ("%%b") do (
set "line=%%c"
if /i "!line:~0,2!"=="HH" >> "%target%\-%%d.csv.txt" echo %%b
)
)
)
ren "%target%\*.csv.txt" *.
)
)
pause
Explanation of the dir switches:
/s - Displays files in specified directory and all subdirectories.
/b - Uses bare format (no heading information or summary).
/o:in - Lists the files in reverse order
/a:d - Displays only folders
Explanation of the %%~fD: expands %A to a fully qualified path name (from for /?)

Create List of file for a directory

I have a directory of files for example:
\1.gif
\1.pdf
\1.doc
\2.gif
\2.pdf
\2.doc
\3.gif
\4.gif
How do I get a file with just the list of files (with extensions) that have unique filenames? (i.e. 3.gif, 4.gif)
Thanks
This does not work with special characters like !, = and more.
#ECHO OFF &SETLOCAL
for %%a in (*) do set ".%%~na=%%~xa"& set /a $%%~na+=1
for /f "tokens=1*delims==." %%a in ('set .') do for /f "tokens=2delims==" %%c in ('set "$%%a"') do if %%c==1 echo(%%a.%%b
i havent tested it, but try this:
#echo off
setlocal enabledelayedexpansion
pushd path\to\dir
for /f %%i in ('dir /b *.gif') do (
find "%%~ni" "%tmp%\u" >nul 2>&1 || echo %%~ni >> "%tmp%\u"
)
for /f %%i in ('type "%tmp%\u"') do (
set inc=
for /f %%j in ('dir %%i.gif /b') do set /a inc+=1
if !inc! EQU 1 (dir /b %%i.* ^|find "log" /v >> log)
)
please feel free to comment if there are any mistakes, not in a position to test it right now.
This will work as long as none of the file names contain the = character:
#echo off
setlocal
for /f "eol== delims==" %%V in ('"set _ 2>nul"') do set "%%V="
for %%F in (*) do if not defined _%%~nF (set "_%%~nF=%%F") else set "_%%~nF=="
for /f "eol== tokens=2 delims==" %%F in ('"set _|findstr /v =="') do #echo %%F
EDIT
If you want to restrict output to only one file type, .gif for example, then all you need is an extra FINDSTR:
#echo off
setlocal
for /f "eol== delims==" %%V in ('"set _ 2>nul"') do set "%%V="
for %%F in (*) do if not defined _%%~nF (set "_%%~nF=%%F") else set "_%%~nF=="
for /f "eol== tokens=2 delims==" %%F in ('"set _|findstr /v ==|findstr /lie .gif"') do #echo %%F

Order files list by batch

I have a long list of individual songs not in folders just songs, and I'd like to move them to the folder of theire artist. the songs are in the following format
artist - songname.flac
I can store them in a list, and echo it, but splitting the artist and songname in 2 vars, I can't seem to figure out.
Could someone help me with the splitting (or if you want even with the rest of the script)
this is what I have so far:
#echo off
setlocal enabledelayedexpansion
set N=0
for %%i in (*) do (
set Files[!N!]=%%~ni
set /a N+=1
)
for /l %%x in (1,1,%N%) do echo.!Files[%%x]!
pause
set SOURCE=c:\temp\test
for /f "delims=-. tokens=1,2" %%i in ('dir /b "%SOURCE%\*.flac"') do echo Artist : %%i Song : %%j
update for full script (got to check if it works with space and special chars in path) :
#echo off
setlocal enabledelayedexpansion
set SOURCE=c:\temp\test
set DESTINATION=c:\temp\test
for /f "tokens=*" %%i in ('dir /b "%SOURCE%\*.flac"') do call :OrderThatMess "%%i"
:OrderThatMess
set NAME=%1
for /f "tokens=1,2 delims=-. " %%j in (%1) do (
set ARTIST=%%j
set TITLE=%%k
if not exist "%DESTINATION%\%ARTIST%" (md "%DESTINATION%\%ARTIST%" )
copy %SOURCE%\%NAME% "%DESTINATION%\%ARTIST%\%TITLE%.flac"
)
#echo OFF &SETLOCAL ENABLEDELAYEDEXPANSION
for %%i in (*.flac) do (
set /a N+=1
FOR /f "tokens=1,2 delims=- " %%o IN ("%%~ni") DO (
set "FilesA[!N!]=%%~o"
set "FilesB[!N!]=%%~p"
)
)
for /l %%x in (1,1,%N%) do echo(!FilesA[%%x]! !filesB[%%x]!
Thanks for the answers ;) Thanks to Kayasax I fixed it
here is the full code:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set SOURCE=C:\music\folder\with\files\
for /f "tokens=1,2 delims=-" %%i in ('dir /b "%SOURCE%\*.flac"') do (
set "folder=%%i"
IF NOT EXIST "%SOURCE%\%%i" (
mkdir "%%i"
)
move "%SOURCE%\%%i-%%j" "%SOURCE%\!folder:~0, -1!\%%i-%%j"
)
pause

How to get a Substring from list of file names

I want to develop the following logic
Read all files in a directory
Extract the first part of the filename – this will be the partner name
Extract anything after the first underscore- this will be filename
Eg: ZZTEST_123_abc_doc.txt  ZZTEST is partner. 123_abc_doc.txt is the filename.
Below is the code I developed
#echo off
setlocal ENABLEDELAYEDEXPANSION
Set Test_Dir=C:\Axway\projects\Cardinal\dosscript\test
cd %Test_Dir%
for /r %%a in (*.*) do (
Set "fname1=%%~nxa"
echo Filename is :!fname1!
for /f "tokens=1 delims=_" %%i in ("!fname1!") do (
Set "partner=%%i"
echo Partner is :!partner!
Set "str_tmp=!partner!_"
echo !str_tmp!
call :strlength length !str_tmp!
echo !length!
set fname=!fname1:~%length%!
echo !fname1:~%length%!
)
)
goto :eof
:strlength
setlocal enableextensions
set "#=%~2"
set length=0
:stringLengthLoop
if defined # (set "#=%#:~1%"&set /A length+=1&goto stringLengthLoop)
endlocal && set "%~1=%length%"
GOTO :EOF
But the result is
ID_ZZRoutingID_filename.txt
Filename is :ZZRoutingID_ZZRoutingID_filename1.txt
Partner is :ZZRoutingID
12
Result: ID_ZZRoutingID_filename1.txt
The result should be ZZRoutingID_filename1.txt but i am getting
ID_ZZRoutingID_filename1.txt.
Please help
The purpose of the length calculation is not clear to me, but I would suggest adding an asterisk following the 1 in your for /f "tokens=1 delims=_". You would then get the "filename" you were looking for through %%j.
I tested it like this:
#echo off
setlocal EnableDelayedExpansion
set source=D:\Program Files\Somewhere
cd %source%
for /r %%i in (*.*) do (
for /f "tokens=1* delims=_" %%j in ( "%%~nxi" ) do (
echo partner: %%j
echo name: %%k
)
)
endlocal
If you do not need to recurse through sub-directories:
#echo off
set source=D:\Program Files\Somewhere
for /f "tokens=1* delims=_" %%i in ( 'dir "%source%" /b /a-d' ) do (
echo partner: %%i
echo filename: %%j
)
dir /b /a-d retrieves the list of a directory's content except its sub-directories:
D:\Program Files\Somewhere>dir /b /a-d
ZZTEST_123_456.txt
ABCDEF_890_FFF.doc
FOOBAR_567_###.zzz

Resources