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
)
)
Related
I followed https://stackoverflow.com/a/16129486/2000557 's example and modified the script for a folder of video files.
#echo off
Setlocal enabledelayedexpansion
Set "Pattern=."
Set "Replace=_"
For %%a in (*.avi) Do (
Set "File=%%~a"
Ren "%%a" "!File:%Pattern%=%Replace%!"
)
For %%a in (*.mkv) Do (
Set "File=%%~a"
Ren "%%a" "!File:%Pattern%=%Replace%!"
)
For %%a in (*.mp4) Do (
Set "File=%%~a"
Ren "%%a" "!File:%Pattern%=%Replace%!"
)
Pause&Exit
Can anyone explain why this also replaces the last dot in the filename (that is a part of the extension) into an underscore. this feels like I was given the fish and not taught how to fish. this script works, but sadly it replaces the last period also.
I'd like to use the script without having to turn on Hide Extensions.
The substitution is overall and can't be limited.
The workaround is easy just use the name without extension for file and append the original extension - this way only one for (for each substitution) is needed.
#echo off & Setlocal EnableDelayedExpansion
For %%A in ("*.*.avi" "*.*.mkv" "*.*.mp4") Do (
Set "File=%%~nA"
Ren "%%A" "!File:.=_!%%~xA" 2>NUL
)
For %%A in ("* *.avi" "* *.mkv" "* *.mp4") Do (
Set "File=%%~nA"
Ren "%%A" "!File: =_!%%~xA" 2>NUL
)
Or this version
For %%A in (*.avi *.mkv *.mp4) Do (
Set "File=%%~nA"
Set "File=!File: =_!"
Set "File=!File:.=_!"
If "%%~nA" neq "!File!" Ren "%%A" "!File!%%~xA"
)
I'm not shure which is more efficient.
You can try with this batch script :
#echo off
Setlocal enabledelayedexpansion
Set "FileType=avi mp4 mkv"
Call :Search_Replace " " "." "!FileType!"
Call :Search_Replace "." "_" "!FileType!"
Timeout -1 & exit
::********************************************************
:Search_Replace <Pattern> <Replace> <FileType>
Set "Pattern=%~1"
Set "Replace=%~2"
#For %%# in (%~3) do (
For %%a in (*.%%#) Do (
Set "File=%%~na"
ren "%%a" "!File:%Pattern%=%Replace%!%%~xa"
)
)
Exit /b
::********************************************************
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
I need a batch file ( Windows CMD is the interpreter, a .bat ) to do this type of task:
1) Search through a folder and its subfolders
2) Find files with the same filename and extension ( aka duplicates )
3) Check if they have the same size
4) If same name + same size, echo all the files except the first one ( practically I need to delete all except one copy )
Thanks for any type of help
This is only an initial script, just for check the files, in a folder and its subfolders, and their size:
#Echo off
Setlocal EnableDelayedExpansion
Set Dir=C:\NewFolder
For /r "%Dir%" %%i in (*) do (
Set FileName=%%~nxi
Set FullPath=%%i
Set Size=%%~zi
Echo "!FullPath!" - SIZE: !Size!
)
Echo.
Pause
This script does what you ask. Just set the ROOT variable at the top to point to the root of your tree.
#echo off
setlocal disableDelayedExpansion
set root="c:\test"
set "prevTest=none"
set "prevFile=none"
for /f "tokens=1-3 delims=:" %%A in (
'"(for /r "%root%" %%F in (*) do #echo %%~znxF:%%~fF:)|sort"'
) do (
set "currTest=%%A"
set "currFile=%%B:%%C"
setlocal enableDelayedExpansion
if !currTest! equ !prevTest! echo "!currFile!"
endlocal
set "prevTest=%%A"
)
But you can make the test more precise by using FC to compare the contents of the files. Also, you can incorporate the DEL command directly in the script. The script below prints out the commands that would delete the duplicate files. Remove the ECHO before the DEL command when you are ready to actually delete the files.
#echo off
setlocal disableDelayedExpansion
set root="c:\test"
set "prevTest=none"
set "prevFile=none"
for /f "tokens=1-3 delims=:" %%A in (
'"(for /r "%root%" %%F in (*) do #echo %%~znxF:%%~fF:)|sort"'
) do (
set "currTest=%%A"
set "currFile=%%B:%%C"
setlocal enableDelayedExpansion
set "match="
if !currTest! equ !prevTest! fc /b "!prevFile!" "!currFile!" >nul && set match=1
if defined match (
echo del "!currFile!"
endlocal
) else (
endlocal
set "prevTest=%%A"
set "prevFile=%%B:%%C"
)
)
Both sets of code may seem overly complicated, but it is only because I have structured the code to be robust and avoid problems that can plague simple solutions. For example, ! in file names can cause problems with FOR variables if delayed expansion is enabled, and = in file name causes a problem with npocmoka's solution.
#echo off
setlocal
for /f "tokens=1 delims==" %%# in ('set _') do (
set "%%#="
)
for /r %%a in (*.*) do (
if not defined _%%~nxa%%~za (
set "_%%~nxa%%~za=%%~fa"
) else (
echo %%~fa
)
)
endlocal
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
I have the script
for /f "delims=" %%i in ('dir "%folder%*.txt" /b /s') do (
set s=%%i
set s=!s:%folder%=!
set new_s=!s:\=!
if "x!new_s!" NEQ "x!s!" (
:ProcessListSource
For /f "tokens=1* delims=\" %%A in ("!s!") do (
if "%%A" NEQ "" (
if "!Folder1!" NEQ "" (
Set Folder1=!Folder1!\!Name!
)else (
Set Folder1=!Name!
)
Set Name=%%A
)
if "%%B" NEQ "" (
set s=%%B
goto :ProcessListSource
)
)
echo Folder is: !Folder1!
echo Name is: !Name!
echo ---------------------
) else (
echo Not a folder !s!
)
)
but it does not work as I would have expected:
The first for is executed only once and also the last echo is printed on the screen.
Given a folder I need the files from subfolders without the given folder and than split them into the folder and file
Ex: folder=C:\test
The for would give me the file C:\test\test1\test2\t.txt
And I need test1\test2 and t.txt
GOTO breaks your FOR /F \ IF context and they can be executed only once.
More simple example:
#echo off
for /l %%S in (1=1=5) do (
echo %%S
goto :inner_label
rem
:inner_label
rem
)
This will print only 1 . Do you really need the GOTO here?
When the parser reads your code, all the code inside your for loop is "considered" as only one command that is readed, parsed and executed. As stated in the npocmaka answer, any goto call takes you out of this "line" of code, ending the process of the for loop.
This is a alternative. Use pushd + xcopy /l /s commands to generate a list of the relative paths of the files.
#echo off
setlocal enableextensions disabledelayedexpansion
set "folder=%cd%"
pushd "%folder%"
for /f "delims=" %%a in ('xcopy /l /s /y * "%temp%"^|findstr /vbr /c:"[0-9]"'
) do for /f "delims=: tokens=1,*" %%b in ("%%~a") do (
echo [%%c] [%%~nxa]
)
popd