2

I'm working on a project which works like that:

  1. take a long video hard subtitled and cut it in a lot of smaller scenes and where each scene lasts the time that it lasts the subtitle to disappear

  2. cut one only picture (maybe the first one or the last one) of each segment of the original video and do it automatically

  3. repeat (copy and paste) the picture extracted as many times as the number of pictures that there are on each fragment that has been cut on the original video

  4. join everything

I have already achieved the point 1) and 2), now I'm trying to achieve point 3) and I need your help, please. Let's say that I have achieved point 2) with this batch script (that I call a.bat) :

pushd %1

if not exist newfiles\ (
mkdir newfiles
)

if not exist newfiles2\ (
mkdir newfiles2
)

:start

for %%F in (*.mov) do (
    md "%%~nF"
    echo "%%~nF"
    ffmpeg -i %%F -r 1 -f image2 -qscale:v 2 "%%~nF\%%~nF_image-%%3d.png"
    copy "%%~nF\%%~nF_image-001.png" ".\newfiles" 
    )
popd

So, I have this situation:

pic1

pic2

pic3

It means that in each folder there is a variable number of images that have been extracted from the *.mov files. Now, I want that the first image on the list of the images located on the relative folders is copied in another folder, as many times as many files there are in the same folder where it is. For example, let's take a look at this folder:

pic4

Here there are 4 images, right? I want to copy the first (or the last) image of the list for 4 times in this folder:

pic5

I would like that someone can help me to improve this batch script (that I call b.bat)...

@echo off

setlocal enabledelayedexpansion
set count=0

for %%x in (*.png) do set /a count+=1
echo %count%

FOR %%F IN (*.png) DO (
 set filename=%%F
 goto tests
)

:tests
echo "%filename%"

for /l %%i in (1,1,%count%) do copy %filename% ..\newfiles2\%%i.png

endlocal
pause

because I figured out that it works only if I put a copy of it in every/each folder,but then I have to enter in each folder to run it,wasting a lot of time. Let's say that I want to run it in the folder where all the others folders are located. How can I modify the script to do so ? This is what happens if I run it on the "root" folder :

pic6

EDIT : thanks to the suggestion of @AlexP I modified the script like this :

@echo off

setlocal enabledelayedexpansion
set count=0

for /d %%d in (render*) do set /a count+=1t

echo %count%
pause

for %%f IN ("%%~d\*") do (
 set filename=%%F
 goto tests
)

:tests
echo "%filename%"

for /l %%i in (1,1,%count%) do copy %filename% .\%%i.png

endlocal
pause

now the var "count" has value 4,but this is wrong. the value that i need is inside each folder that starts with the word render* ; so,since I have 4 pics inside the "render00003211" folder the value is 4; 5 pics under "render00003266" the value is 5 and so on..

UPDATE : I've ordered sequentially the names of the pictures by placing this script inside the Duplicates folder...

@echo off
setlocal enabledelayedexpansion
mkdir pics
copy *.png .\pics
del *.png

for /d /r %%a in (%1\*.*) do (
    set /a counter=0
    for %%b in ("%%a\*.*") do (
        set /a counter += 1
        set zcounter=0000!counter!
        set source="%%~fb"
        set target="pic!zcounter:~-4!%%~xb"
        echo Renaming !source! to !target!
        ren !source! !target!
    )
) 
Marietto
  • 201
  • 2
  • 9

1 Answers1

0
for /l %%i in (1,1,%count%) do copy %filename% %somewhere%

From for /?:

FOR /L %variable IN (start,step,end) DO command [command-parameters]

The set is a sequence of numbers from start to end, by step amount. So (1,1,5) would generate the sequence (1 2 3 4 5) and (5,-1,1) would generate the sequence (5 4 3 2 1).

Here is a script which implements what I understand to be the requirements:

   @echo off

:: This script will visit each subdirectory of the directory from where it is
:: run; it will take the first file found in that subdirectory and copy it to
:: the directory ..\Duplicates as many times as there are files in that
:: subdirectory; the names of the copied files are taken from the name of the
:: subdirectory with a numeric suffix appended, and have the extension of the
:: copied file. If ..\Duplicates does not exist then it is created.

   setlocal

   echo Working in directory "%CD%"
   if not exist ..\Duplicates mkdir ..\Duplicates
   if not exist ..\Duplicates\. (
     echo Destination ..\Duplicates does not exist, and I cannot create it.
     exit /b
   )
   for /d %%d in (*) do call :duplicateDir "%%~d"
   exit /b

:duplicateDir

   echo * "%~1"
   set COUNT=0
   set "SUBNAME=%~n1"
   set SUBFILE=&
   set SUBEXT=&
   for %%f in ("%~1\*") do call :duplicateFile "%%~f"
   echo   "%SUBFILE%" copied %COUNT% times
   exit /b

:duplicateFile

   if not defined SUBFILE set "SUBFILE=%~1"
   if not defined SUBEXT set "SUBEXT=%~x1"
   set /a COUNT=COUNT+1
   echo copy "%SUBFILE%" "..\Duplicates\%SUBNAME%-%COUNT%%SUBEXT%"
:: copy "%SUBFILE%" "..\Duplicates\%SUBNAME%-%COUNT%%SUBEXT%" >nul
   exit /b

Note that instead of actually doing the copying the script displays the command which would be executed. When you are happy with it, comment out the echo copy and uncomment the copy.

Community
  • 1
  • 1
AlexP
  • 4,370
  • 15
  • 15
  • I figured out that the batch script "b.bat" works only if I put a copy of it in every folder,but then I have to enter in each folder to run it,wasting a lot of time. Let's say that I want to run it in the folder where all the others are located,how can I modify the script to do so ? – Marietto Jun 18 '18 at 20:52
  • can you post all the content of the b.bat script,please ? – Marietto Jun 18 '18 at 21:14
  • @JohnConnor: I'm sorry, but this site is intended to be used by programmers to share and enhance their skills. Anyway, here is a hint: your script works fine from any directory; you *do not* need to put a copy of it there, you need to *invoke* it from there. (And the structures in the filesystem are "directories"; "folders" are pretty pictures shown in a GUI, which may or may not correspond to filesystem directories.) – AlexP Jun 18 '18 at 21:38
  • ok. so,this is how I understood your suggestion : @echo off setlocal enabledelayedexpansion set count=0 for /d %%d in (render*) do set /a count+=1 echo %count% pause for %%f IN ("%%~d\*") do ( set filename=%%F goto tests ) :tests echo "%filename%" for /l %%i in (1,1,%count%) do copy %filename% .\%%i.png endlocal pause ; the var "count" now has value 4,but this is wrong. the value that i need is inside each folder that starts with the word render* ; so,I have 4 pics inside the "render00003211" folder ; 5 pics under "render00003266" folder and so on... – Marietto Jun 18 '18 at 21:43
  • please can you satisfy my curiosity ? I looked on stackoverflow for a possible solution for what I want to achieve and I have seen that sometimes the user says that he does not know the programming language at all, but he is helped a lot. instead you told to me : "I'm sorry, but this site is intended to be used by programmers to share and enhance their skills". Sometimes this site does not work like you said. Let's take for example the users who does not know at all a programming language. Is it correct in your opinion does not offer some help to these users ? – Marietto Jun 18 '18 at 22:59
  • for example,this : https://stackoverflow.com/questions/11004045/batch-file-counting-number-of-files-in-folder-and-storing-in-a-variable/15485610 – Marietto Jun 18 '18 at 23:02
  • OK, you conviced me. – AlexP Jun 18 '18 at 23:11
  • I have updated the answer to include what I understood to be the problem. – AlexP Jun 18 '18 at 23:35
  • yeah,you have understood well the situation and you wrote a good script for me. I admit that it was out of my little knowledge on the batch scripting. Anyway,only now I reaized that there is a big error on the logic behind the script and it is my fault,not your. The duplicated files created on the duplicates folder aren't in sequential order,so when I give them to virtualdub to create an avi file,it accepts only the first 4,from "render00003211-1.png" to "render00003211-4.png",files from "render00003256-1.png" to the end are ignored... – Marietto Jun 19 '18 at 07:54
  • I fixed with this : @echo off setlocal enabledelayedexpansion mkdir pics copy *.png .\pics del *.png for /d /r %%a in (%1\*.*) do ( set /a counter=0 for %%b in ("%%a\*.*") do ( set /a counter += 1 set zcounter=0000!counter! set source="%%~fb" set target="pic!zcounter:~-4!%%~xb" echo Renaming !source! to !target! ren !source! !target! ) ) – Marietto Jun 19 '18 at 12:09