Batch renumber files that start with a digit - windows

I use this batch script very often to collate images side by side using ImageMagick, and it serves well the purpose, unless I am facing images whose file names start with digits.
Example:
ThisImage1.JPG
ThisImage2.JPG
...
ThisImage6.JPG
will be first renamed to:
A1.JPG
A2.JPG
...
A6.JPG
then collated 2 by 2 into:
B1.JPG
B3.JPG
B5.JPG
But if the images are originally named like:
111.JPG
112.JPG
...
116.JPG
then the preliminary renaming will be:
A2.JPG
A3.JPG
...
A7.JPG
which is a mistake of course...
Can this be solved?
My batch script:
SETLOCAL EnableDelayedExpansion
SET IMCONV="%PROGRAMFILES%\ImageMagick-7.0.4-Q16\Convert"
SET COUNT=0
setlocal ENABLEDELAYEDEXPANSION
FOR /R %%T IN (*.jpg) DO (
SET /A COUNT=!COUNT!+1
REN %%T A!COUNT!.jpg
)
:EOF
#echo off
set count=0
for %%x in (*.jpg) do set /a count+=1
set /a demi=%count% / 2
FOR /L %%x IN (1,2,%count%) DO (
set /a y = %%x + 1
%IMCONV% A%%x.jpg A!y!.jpg +append B%%x.jpg
)
endlocal

Related

batch script loop in win cmd

I need to merge multiple ".ts" files in each directory.
The file structure is like this:
file structure
I've tried loop code and it worked well in a one-layer structure:
for /l %%x in (1,1,24) do (
copy /b %%x\*.ts new_%%x.ts
)
pause
I tried to add another loop to run a double-layer structure, it won't work in the following code:
for /l %%x in (1,24,49) do (
for /l %%a in (%%x,1,%%x+23) do (
copy /b %%x\%%a\*.ts \%%x\new_%%a.ts
)
)
The problem is the values can't be summed here:
%%x+23
Then I tried to calculate the value before putting it in the second loop:
for /l %%x in (1,24,49) do (
set /a endvalue=%%x+23
for /l %%a in (%%x,1,endvalue) do (
copy /b %%x\%%a\*.ts \%%x\new_%%a.ts
)
)
And the code still doesn't work.
Did I miss something? How can I fix it?
Thanks,
CJ
Use delayed environment variable expansion
#echo off
setlocal EnableDelayedExpansion
for /l %%x in (1,24,49) do (
set /a beginvalue=%%x
set /a endvalue=%%x + 23
for /l %%a in (!beginvalue!,1,!endvalue!) do (
echo %%a
)
)

How to break a "for /l" loop in a batch script?

I'm a newbie the commands of a Batch Script on Windows
I have a question about a batch file that I'm writing.
How to break from the "for /l" loop ?
In the script below, I would like to copy x number files from one folder to another
However, after the break the first loop, the second loop doesn't works fine,
it copied all files in the source folder to the destination folder.
Thank you for your help :)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET Source=C:\Data
SET Target1=C:\Work\bak1
SET Target2=C:\Work\bak2
SET Target3=C:\Work\bak3
SET /A days=13
SET /A weekNum=9
SET /A MaxLimit=3
SET /A Count=0
for /l %%x in (1, 1, %days%) do (
if %%x LEQ 9 (
FOR /F %%G IN ('DIR /B "%Source%"\*.*') DO (
copy /y "%Source%"\"%%G" "%Target1%"
set /a Count=Count+1
if !Count!==%MaxLimit% call :step1
)
:step1
REM SET /A "x=x + 1"
REM echo %%x
IF %%x LEQ 1 IF %weekNum% EQU 9 (
FOR /F %%G IN ('DIR /B "%Source%"\*.*') DO (
copy /y "%Source%"\"%%G" "%Target2%"
set /a Count=Count+1
if !Count!==%MaxLimit% call :step2
)
:step2
REM SET /A "x=x + 1"
REM echo %%x
)
) else (
REM Copy file to Target3
)
)

Edit text after dot with batch script

I want to remove three digits after dot in last 3 columns with batch file (windows). Note that dots can be present in other columns.
This is a sample of my data:
4216118,'0806010709','ljubičasti ','Hita kirška ambnta',1,'Eriiti (vk, kk)','X','Uđaj za heološke prege','Celyn1800 ','Hni Sak','Hemlogja','2016-06-08 11:42:05.040','2016-06-08 11:41:42.122','2016-06-08 11:49:49.370'
4216081,'0806010387','ljubičasti ','Oća doven.amb. - VANJA',1,'Erii (vk, kk)',,'Urj za heoške prage','Adia 120 R','Reni','Hlogija','2016-06-08 08:52:13.962','2016-06-08 08:51:57.067','2016-06-08 11:08:26.504'
4216667,'1506010909','ljčasti ','tna ambuta kke za invne bolesti',1,'Erciti (vk, kk)',,'Uj za hemloške prge','Cell-Dyn 1800 R','Hi','Hemagija','2016-06-15 21:24:14.646','2016-06-15 21:24:03.523','2016-06-15 21:26:58.871'
4213710,'0905010991','ljubičasti ','Hna kira amnta',1,'Eociti (vk, kk)','X','Uđaj za hemloške prage','Cel1800 ','Hi Sak','Hemlogja','2016-05-09 17:52:32.231','2016-05-09 17:52:26.319','2016-05-09 18:31:33.643'
Example:
Before:
'2016-06-08 11:49:49.370'
After:
'2016-06-08 11:49:49'
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q47642335.txt"
SET "outfile=%destdir%\outfile.txt"
(
FOR /f "delims=" %%a IN ('more %filename1%') DO (
SET "line=%%a"
ECHO !line:~0,-57!!line:~-53,-31!!line:~-27,-5!!line:~-1!
)
)>"%outfile%"
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
I used a file named q47642335.txt containing your data for my testing.
Produces the file defined as %outfile%
Sadly, cmd doesn't play nicely with unicode files, so there will be some modification to the data. Essentially, read each line and pick the line-portions to be concatenated, using - substringing values to select from the end of the line, which is of a consistent structure.
Try this, without any guaranties. Regarding your example, expect you want remove last three digits AND dot, unlike your describe to remove three digits AFTER dot.
#echo off & setlocal ENABLEDELAYEDEXPANSION > out.txt
for /f "tokens=1-15 delims=," %%a in (data.txt) do (
set "string="
call :process "%%a" "%%b" "%%c" "%%d" "%%e" "%%f" "%%g" "%%h" "%%i" "%%j" "%%k" "%%l" "%%m" "%%n" "%%o"
)
exit /B
:process
echo %~1| findstr /R /C:"[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*\.[0-9][0-9][0-9]" >NUL
if not errorlevel 1 (
set "str=%~1"
set "str=!str:~0,-5!"
if defined string (set "string=!string!,!str!'") else (set "string='!str!'")
) else (
set "str=%~1"
if defined string (set "string=!string!,!str!") else (set "string='!str!'")
)
shift
if not "%~1"=="" (goto :process) else (echo !string!>>out.txt)
GOTO:EOF

Windows batch: get substring of variable length in loop

I would like to retrieve a substring of variable length in a for loop as follows:
#ECHO off
setlocal EnableDelayedExpansion
CALL :strlen orglength %cd%
FOR /F "DELIMS==" %%d in ('DIR /AD /B /S') DO (
SET a=%%d
CALL :strlen curpatlen !a! ::sets curpatlen the length of string a
SET /a l=%orglength%-!curpatlen!
::crucial part: get the last l characters of a
CALL SET curpat=%!a:~!l!!% ::doesnt work
ECHO !curpat!
)
:strlen <resultVar> <stringVar>
(
set "s=!%~2!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
set "%~1=%len%"
exit /b
)
The main idea:
Starting in the directory X of the batch file, I create a folder named X-svg (not part of the code I posted on purpose). Then, I go through all subdirectories of X looking for .pdf files which I want to convert to .svg files(future work). For all subdirectories of X which contain a .pdf I want to create a corresponding folder in X-svg that contains only the converted .svg file. In order to create the corresponding folders in X-svg, my idea was to keep the string length of the directory of X-svg in orglength, compute the length of the current path X/Y and the difference between both in order to be able to create the folder X-svg/Y, into which I would then convert the available .pdf.
What I would like to do in the code above: given a length orglength of a path string org, I want to get the difference string between org and the current path, %%d, which avries witch each loop. An example with static substring length of 4 would be:
REM FOR loop over %%d
set str=%%d
set str=!str:~-4!
In my case, instead of 4, I need a variable length which is calculated during the for loop.
Thank You in Advance
Edit: This code works for me:
#ECHO off
CALL :changefolder %cd% "svg"
xcopy "%cd%\*.pdf" "%Result%\" /T /S
for /f "delims=" %%A in ('cd') do (
set foldername=%%~nxA
)
setlocal EnableDelayedExpansion
FOR /F "DELIMS==" %%f in ('DIR "*.pdf" /B') DO (
set varpdf=%%f
set var=!varpdf:~0,-3!
"C:\Program Files (x86)\Inkscape\inkscape.exe" -f !varpdf! -l %Result%\!var!svg
)
FOR /F "DELIMS==" %%d in ('DIR /AD /B /S') DO (
set PassedString=%%d
call set tempstring=%%PassedString:\%foldername%\=\%foldername%-svg\%%
FOR /F "DELIMS==" %%f in ('DIR "%%d\*.pdf" /B') DO (
set varpdf=%%f
set var=!varpdf:~0,-3!
"C:\Program Files (x86)\Inkscape\inkscape.exe" -f %%d\!varpdf! -l !tempstring!\!var!svg
)
)
endlocal
goto :eof
:changefolder
set Path1=%~1
set Path2=%~2
if {%Path1:~-1%}=={\} (set Result=%Path1:~-1%%Path2%) else (set Result=%Path1%-%Path2%)
goto :eof
May not be best but works
Test this to see if it creates the folders that you need:
xcopy "x:\main\folder\*.pdf" "c:\x-org\" /T /S

Batch split a text file

I have this batch file to split a txt file:
#echo off
for /f "tokens=1*delims=:" %%a in ('findstr /n "^" "PASSWORD.txt"') do for /f "delims=~" %%c in ("%%~b") do >"text%%a.txt" echo(%%c
pause
It works but it splits it line by line. How do i make it split it every 5000 lines. Thanks in advance.
Edit:
I have just tried this:
#echo off
setlocal ENABLEDELAYEDEXPANSION
REM Edit this value to change the name of the file that needs splitting. Include the extension.
SET BFN=passwordAll.txt
REM Edit this value to change the number of lines per file.
SET LPF=50000
REM Edit this value to change the name of each short file. It will be followed by a number indicating where it is in the list.
SET SFN=SplitFile
REM Do not change beyond this line.
SET SFX=%BFN:~-3%
SET /A LineNum=0
SET /A FileNum=1
For /F "delims==" %%l in (%BFN%) Do (
SET /A LineNum+=1
echo %%l >> %SFN%!FileNum!.%SFX%
if !LineNum! EQU !LPF! (
SET /A LineNum=0
SET /A FileNum+=1
)
)
endlocal
Pause
exit
But i get an error saying: Not enough storage is available to process this command
This will give you the a basic skeleton. Adapt as needed
#echo off
setlocal enableextensions disabledelayedexpansion
set "nLines=5000"
set "line=0"
for /f "usebackq delims=" %%a in ("passwords.txt") do (
set /a "file=line/%nLines%", "line+=1"
setlocal enabledelayedexpansion
for %%b in (!file!) do (
endlocal
>>"passwords_%%b.txt" echo(%%a
)
)
endlocal
EDITED
As the comments indicated, a 4.3GB file is hard to manage. for /f needs to load the full file into memory, and the buffer needed is twice this size as the file is converted to unicode in memory.
This is a fully ad hoc solution. I've not tested it over a file that high, but at least in theory it should work (unless 5000 lines needs a lot of memory, it depends of the line length)
AND, with such a file it will be SLOW
#echo off
setlocal enableextensions disabledelayedexpansion
set "line=0"
set "tempFile=%temp%\passwords.tmp"
findstr /n "^" passwords.txt > "%tempFile%"
for /f %%a in ('type passwords.txt ^| find /c /v "" ') do set /a "nFiles=%%a/5000"
for /l %%a in (0 1 %nFiles%) do (
set /a "e1=%%a*5", "e2=e1+1", "e3=e2+1", "e4=e3+1", "e5=e4+1"
setlocal enabledelayedexpansion
if %%a equ 0 (
set "e=/c:"[1-9]:" /c:"[1-9][0-9]:" /c:"[1-9][0-9][0-9]:" /c:"!e2![0-9][0-9][0-9]:" /c:"!e3![0-9][0-9][0-9]:" /c:"!e4![0-9][0-9][0-9]:" /c:"!e5![0-9][0-9][0-9]:" "
) else (
set "e=/c:"!e1![0-9][0-9][0-9]:" /c:"!e2![0-9][0-9][0-9]:" /c:"!e3![0-9][0-9][0-9]:" /c:"!e4![0-9][0-9][0-9]:" /c:"!e5![0-9][0-9][0-9]:" "
)
for /f "delims=" %%e in ("!e!") do (
endlocal & (for /f "tokens=1,* delims=:" %%b in ('findstr /r /b %%e "%tempFile%"') do #echo(%%c)>passwords_%%a.txt
)
)
del "%tempFile%" >nul 2>nul
endlocal
EDITED, again: Previous code will not correctly work for lines starting with a colon, as it has been used as a delimiter in the for command to separate line numbers from data.
For an alternative, still pure batch but still SLOW
#echo off
setlocal enableextensions disabledelayedexpansion
set "nLines=5000"
set "line=0"
for /f %%a in ('type passwords.txt^|find /c /v ""') do set "fileLines=%%a"
< "passwords.txt" (for /l %%a in (1 1 %fileLines%) do (
set /p "data="
set /a "file=line/%nLines%", "line+=1"
setlocal enabledelayedexpansion
>>"passwords_!file!.txt" echo(!data!
endlocal
))
endlocal
Test this: the input file is "file.txt" and output files are "splitfile-5000.txt" for example.
This uses a helper batch file called findrepl.bat - download from: https://www.dropbox.com/s/rfdldmcb6vwi9xc/findrepl.bat
Place findrepl.bat in the same folder as the batch file or on the path.
#echo off
:: splits file.txt into 5000 line chunks.
set chunks=5000
set /a s=1-chunks
:loop
set /a s=s+chunks
set /a e=s+chunks-1
echo %s% to %e%
call findrepl /o:%s%:%e% <"file.txt" >"splitfile-%e%.txt"
for %%b in ("splitfile-%e%.txt") do (if %%~zb EQU 0 del "splitfile-%e%.txt" & goto :done)
goto :loop
:done
pause
A limitation is the number of lines in the file and the real largest number is 2^31 - 1 where batch math tops out.
#echo off
setlocal EnableDelayedExpansion
findstr /N "^" PASSWORD.txt > temp.txt
set part=0
call :splitFile < temp.txt
del temp.txt
goto :EOF
:splitFile
set /A part+=1
(for /L %%i in (1,1,5000) do (
set "line="
set /P line=
if defined line echo(!line:*:=!
)) > text%part%.txt
if defined line goto splitFile
exit /B
If the input file has not empty lines, previous method may be modified in order to run faster.

Resources