I'm trying to build a script for one of our remote media players and am trying to get it to update once a file shows up in the dropbox. I need it to check the first 5 of the title against MM-DD and if they match then play the video in question. Playing the video is no issue, neither are the archives. My issue right now is that when I try to make a for loop for the files in the location I'm getting the syntax of the command is incorrect or "x" was not expected at this time. also, my date is being formatted like this: 05 -02, and I dont know why.
:::::::::::::::::::::::::::::::::::::::::::::: Get Date :::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Use WMIC to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
IF "%%~L"=="" goto s_done
Set _mm=00%%J
Set _dd=00%%G
)
:s_done
:: Pad digits with leading zeros
Set _mm=%_mm:~-2%
Set _dd=%_dd:~-2%
::Finalize Date
Set date=%_mm%-%_dd%
echo %date%
::::::::::::::::::::::::::: Check the downloads folder for completed video files :::::::::::::::::::::::::::::::
:: Loop through all files
:loop
for %%a IN ("dir \Dropbox\Trailer") DO (
::IF the name is not blank, get the first 5 characters of the video name
set first5=%a:~0,5%
::Compare those characters to the date
IF "%first5%" == "%date%" (
taskkill /im wmplayer.exe /t
::::::::::::::: Archive all previous Videos :::::::::::::
for /r %%i in ("dir \Dropbox\Trailer") do (
xcopy /s (%%i) "dir \Archived_Shows\"
)
ping localhost
"C:\Program Files\Windows Media Player\wmplayer.exe" "C:\Dropbox\Trailer\%%a" /fullscreen
:::::::::::::::::::::::::::::::: Exit if new video is running ::::::::::::::::::::::::::::::::::::::
exit
)
)
goto :loop
I'm not sure exactly what your script is supposed to be doing but here is an example based on my understanding.
#Echo Off
CD "Dropbox\Trailer" 2>Nul || Exit /B
For /F "Tokens=1-2" %%A In (
'WMIC Path Win32_LocalTime Get Day^,Month^|FindStr [1-9]'
) Do Set /A _dd=10%%A,_MM=10%%B
Set "DString=%_MM:~-2%-%_dd:~-2%"
:Loop
If Not Exist "%DString%*" (
Timeout 300 /NoBreak
GoTo Loop
)
TaskKill /IM WMPlayer.exe /T 2>Nul
Timeout 10 /NoBreak >Nul
XCopy "." "%~dp0Archived_Shows" /S /D /I
For %%A In ("%DString%*") Do (
"%ProgramFiles%\Windows Media Player\wmplayer.exe" "%%A" /FullScreen
)
GoTo Loop
If no matching file is found it currently checks for new ones every 300 seconds, (5 minutes). If a matching file is found, the loop only resumes once you close WMPlayer. You can change that timespan on line 11 as per your preference.
You are setting the variable %date%, which is a system dynamic variable. Attempting to modify the contents is an unrecommended act, so instead, use another name.
Also, I have simplified the get-and-trim MM-DD part, and it works properly for me.
for /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
IF "%%~L"=="" goto s_done
Set _mm=00%%~J
Set _dd=00%%~G
)
:s_done
::Finalize Date
Set titleDate=%_mm:~-2%-%_dd:~-2%
echo %titleDate%
pause
Related
I am trying to rename some MP4 files based on file size of mp4 files in another directory. I want to name all files with identical sizes to same name. Meaning if the file size of the source file matches the size of file in the comparison directory, the source file is renamed to whatever the compared file is named. Because both directories need to be read recursively I'm thinking it would be easier to make a list for comparison with the info in it in 2 columns by using the DIR /s /b echo %%~zs>>filesizelist.txt command giving me a list like
123456789 movie.mp4
987654321 movie2.mp4
Then pass all source mp4s to the batch file and if %%~za matches a value in first column then ren the file to the
corresponding filename. Is this the best path? I tried to script it to work on the fly and that was both a no-go and the source of my 3 day headache(plus the reference list rarely changes and is obviously easily updated). Can someone please assist me with the script?
I do some test with my mp4, and the code works, and for you perform your test, you w´ll need change/put this 2 line above with the path to your folder/directory (one to keep and another to compare), by replacing in the line code is like this:
`set "_target_to_keeped=C:\Users\ecker\Videos\Target"`
`set "_target_to_rename=C:\Users\ecker\Videos\Ren_it"`
You need add the folder where are files to keep and files to rename (if size+name match) on same lines where are the 2 lines code up in this test (sorry not explain in good English, my English is not help me). By now, is late 01:53, i need sleep... yep! so, have nice code!
#echo off && setlocal enableextensions enabledelayedexpansion
cd /d "%~dp0"
set /a _cnt_in_looping= 1 - 1
set /a _cnt_files_size= 1 - 1
set "_target_to_keeped=C:\Users\ecker\Videos\Target"
set "_target_to_rename=C:\Users\ecker\Videos\Ren_it"
cd /d "!_target_to_keeped!"
for /f "tokens=* delims=^ " %%i in ('^<nul dir /o-d /on /b "*.mp4" 2^> nul ^| find "" /v /c') do set _cnt_in_looping=%%i
for /f "tokens=* delims=^ " %%i in ('^<nul dir /o-d /on /b "*.mp4"') do (
set "_file_now_keep=%%i"
set "_file_now_keeped=%%~zi %%i"
call :_to_compare_:
)
set /a _total_files_renamed=!_cnt_in_looping! - !_cnt_files_size!
set /a _total_files_n_chang=!_total_files_renamed! - !_cnt_in_looping! * -1
echo/Total of files renamed = !_total_files_renamed!
echo/Total of files n chang = !_total_files_n_chang!
endlocal
goto :_end_of_file_:
:_to_compare_:
if not exist "!_file_now_keep!" exit /b
for /f "tokens=*" %%I in ('^<nul dir /o-d /on /b "!_file_now_keep!"') do (
set "_file_now_compare=%%~zI %%I"
set "_path_now_compare=%%~dpI"
if "!_file_now_compare!" == "!_file_now_keeped!" (
rename "!_path_now_compare!\%%I" "%%~zI %%I"
echo/ rename "%%~I" "%%~zI %%I"
if ["!errorlevel!"]==["0"] call set /a _cnt_files_size=!_cnt_files_size! + 1
timeout /t 10
)
)
exit /b
:_end_of_file_:
I need to scan through a drive and list all the folders containing only a single file, entitled "Thumbs v0.1.db". I have cobbled together the following code but it doesn't seem to work. Either the batch file exits prematurely, or it completes without listing any such subdirectories! I would be very thankful if someone could point out the problem.
#echo off
SET /P folder="Please enter root directory to seach in: "
SET writefile="C:\Users\MYNAME\Desktop\Thumbs.txt"
SET tmp="C:\Users\MYNAME\Desktop\rowcounttmp"
Echo Searching for directories, please wait...
echo Thumbs v0.1.db-only directories in %folder% > %writefile%
cd /D %folder%
for /d /r %1 %%A in (.) do (
dir /a /b "%%~fA" 2>nul | find /c /v "~StringWhichWillNotAppear~" > %tmp%
set var=<%tmp%
if [%var%] == 1 dir /a /b "%%~fA" 2>nul | findstr /i "Thumbs v0.1.db" >nul && echo %%~fA >> %writefile%
)
del %tmp%
Pause
Thanks
EDIT:
Thanks to #peter-wright, I now have this: Have I implemented his suggestions incorrectly? It seems to crash for certain filepaths (specifically the read-only drive I am trying to scan through) and there are still no results appearing.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
Color 0A
SET /P folder="Please enter root directory to seach in: "
SET writefile="C:\Users\MYNAME\Desktop\Thumbs.txt"
SET tempfile="C:\Users\MYNAME\Desktop\rowcounttmp"
Echo Searching for directories, please wait...
echo Thumbs v0.1.db only directories in %folder% > %writefile%
cd /D %folder%
for /d /r %1 %%A in (.) do (
dir /a /b "%%~fA" 2>nul | find /c /v "~StringWhichWillNotAppear~" > %tempfile%
set var=<%tempfile%
if !var! == 1 dir /a /b "%%~fA" 2>nul | findstr /i "Thumbs v0.1.db" >nul && echo %%~fA >> %writefile%
)
del %tempfile%
Pause
The variable var is being set within a BLOCK (parenthesised series of statements.)
Any %var% within a block is replaced by the value of that var WHEN THE BLOCK IS PARSED, not when it is EXECUTED.
To access the RUN-TIME value of var use !var! AFTER having invoked delayedexpansion with a SETLOCAL ENABLEDELAYEDEXPANSION statement (probably best implemented immediately after your #echo on.
Danger, Will Robinson : DO not use tmp as a variable name - tmp is a magic variable with special meaning to batch. Others may be listed by invoking
SET
from the prompt. Also avoid DATE, TIME, RANDOM, CD and a few others. And really not a good idea to use executable names or batch keywords either...
tip:
try using
FOR /F "delims=" %%i in ('dir /s /a /b /a-d "Thumbs v0.1.db" ') do (
and then %%~dpi will be assigned the names of the directories that CONTAIN the target file. If the count-of-files in these directories is not ==1 then it is not alone...
1 echo off
2
3 echo Please enter a date
4 set /p a=
5 echo %a%
6 for /D %%d in (M:\Serienbriefauftrag\*) do (
7 if not exist %%d\Erledigt\*.bat echo %%d
8 )
9 pause
10 for /d %%b in (dir M:\Serienbriefauftrag\%%d /T:C)
11 echo %%b
12 pause
The Code works fine until line 10 (syntax error) the aim is, to get the creation date of the folder compare it with "%a%" and and if it's under the entered date "%a%", the folder should be moved. but somehow...
found a way to get the creation date
if not exist %%d\Erledigt\*.bat echo %%~td|findstr /i /l
the new task is to make the output "calculateable"
Two things:
1) In line 10 %%d is undefined (empty), since the scope of the first loop (where it is defined) is left in line 8.
You can set another variable to %%d to be able to use it after the loop ends, but be careful. In batch using set in for loops is a bit tricky. To get around the aweful use of delayed variable expansion, I would suggest to you staying inside of the loop while doing your work.
#echo off
set /p a=Please enter a date:
for /d %%d in (M:\Serienbriefauftrag\*) do (
if not exist %%d\Erledigt\*.bat (
:: Do whatever you want with %%d in here
echo "%%d"
)
)
pause
2) The syntax of your second loop is wrong. You are missing the do before the loop body and /d lets the loop iterate over all folders in a specified directory. dir M:\Serienbriefauftrag\%%d /T:C is not a directory but a command.
If you want to iterate over the output of that command, you have to use /f and put the contents of the paranthesis in single quotes, like that ('dir M:\Serienbriefauftrag\%%d /T:C').
I can't seem to understand how batch files add yyyy/mo/dd/hh/mm/ss to the beginning of filenames. (Using Windows 7) Accuracy to the second is important.
It doesn't actually have to be a batch file, it just has to be a small program which can be executed by Directory Monitor whenever I add files to a folder: http://brutaldev.com/page/Directory-Monitor.aspx
I only imagine that a batch file would be the simplest and most efficient approach, but any other suggestions are welcome.
I work with many sequentially numbered files with overlapping filenames and I need a quick way to rename them whenever I add them to a folder such that there will never be any file with the same name yet they will still remain in sequential order. This is how I thought of adding the current date and time to the beginning of the filename and why seconds are important, since I can easily add multiple sets to a folder in under a minute but certainly not under a second. It would be ideal if the batch file could ignore file extensions and simply add the current date/time to the beginning of any file added to the folder.
The first four lines of this code will give you reliable YY DD MM YYYY HH Min Sec variables in XP Pro and higher.
#echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
:: this line will rename the files in the current folder which haven't already
:: been renamed by checking for the fullstamp format at the start of the line
:: but it will skip this batch file
for /f "delims=" %%a in ('dir /b /a-d ^|findstr /v "^[0-9]*-[0-9]*-[0-9]*_[0-9]*-[0-9]*-[0-9]*" ') do if /i not "%%a"=="%~nx0" ren "%%a" "%fullstamp% - %%a"
pause
#ECHO off
SETLOCAL
IF [%1] NEQ [] goto s_start
:: Author - Simon Sheppard, July 2003
:: Tested for Windows NT, 2K, XP
ECHO STAMPME.cmd
ECHO REName a file with the DATE/Time
ECHO.
ECHO SYNTAX
ECHO STAMPME TestFile.txt
ECHO.
ECHO STAMPME "Test File.txt"
ECHO.
ECHO STAMPME "c:\docs\Test File.txt"
ECHO.
ECHO In a batch file use CALL STAMPME ...
:: To change the filename format just change around the last line below
GOTO :eof
:s_start
SET _file=%~n1%
SET _pathname=%~f1%
SET _ext=%~x1%
::Get the date
:: note ISO 8601 date format would require 4 digit YYYY Year)
FOR /f "tokens=6-8 delims=/ " %%G IN ('NET TIME \\%computername%') DO (
SET _mm=%%G
SET _dd=%%H
SET _yy=%%I
)
:: Get the time
FOR /f "tokens=2-4 delims=:." %%G IN ('cmd /c "time<nul"') DO (
SET _hr=%%G
SET _min=%%H
SET _sec=%%I
GOTO :done
)
:done
ECHO Today is Year: [%_yy%] Month: [%_mm%] Day: [%_dd%]
ECHO The time is: [%_hr%]:[%_min%]:[%_sec%]
REN "%_pathname%" "%_hr%-%_min%-%_sec%#%_file%%_ext%"
This seems to work for me
I'd prefer solutions, that are not dependent to local settings (wmic gives always the same format):
#echo off
setlocal EnableDelayedExpansion
for %%a in (a.*) do (
for /f %%i in ( 'wmic os get localdatetime /value ^|find "Local"' ) do set %%i
set ldt=!LocalDateTime:~0,4!-!LocalDateTime:~4,2!-!LocalDateTime:~6,2!-!LocalDateTime:~8,2!-!LocalDateTime:~10,2!-!LocalDateTime:~12,2!-!LocalDateTime:~15,3!
echo seconds ### ren %%a !LocalDateTime:~0,14!%%a
echo milliseconds ### ren %%a !LocalDateTime:~0,18!%%a
echo with separator ### ren %%a !ldt!-%%a
)
I have up to 4 files based on this structure (note the prefixes are dates)
0830filename.txt
0907filename.txt
0914filename.txt
0921filename.txt
I want to open the the most recent one (0921filename.txt). how can i do this in a batch file?
Thanks.
This method uses the actual file modification date, to figure out which one is the latest file:
#echo off
for /F %%i in ('dir /B /O:-D *.txt') do (
call :open "%%i"
exit /B 0
)
:open
start "dummy" "%~1"
exit /B 0
This method, however, chooses the last file in alphabetic order (or the first one, in reverse-alphabetic order), so if the filenames are consistent - it will work:
#echo off
for /F %%i in ('dir /B *.txt^|sort /R') do (
call :open "%%i"
exit /B 0
)
:open
start "dummy" "%~1"
exit /B 0
You actually have to choose which method is better for you.
Sorry, for spamming this question, but I just really feel like posting The Real Answer.
If you want your BATCH script to parse and compare the dates in filenames, then you can use something like this:
#echo off
rem Enter the ending of the filenames.
rem Basically, you must specify everything that comes after the date.
set fn_end=filename.txt
rem Do not touch anything bellow this line.
set max_month=00
set max_day=00
for /F %%i in ('dir /B *%fn_end%') do call :check "%%i"
call :open %max_month% %max_day%
exit /B 0
:check
set name=%~1
set date=%name:~0,4%
set month=%date:~0,2%
set day=%date:~2,2%
if /I %month% GTR %max_month% (
set max_month=%month%
set max_day=%day%
) else if /I %month% EQU %max_month% (
set max_month=%month%
if /I %day% GTR %max_day% (
set max_day=%day%
)
)
exit /B 0
:open
set date=%~1
set month=%~2
set name=%date%%month%%fn_end%
start "dummy" "%name%"
exit /B 0
One liner, using EXIT trick:
FOR /F %%I IN ('DIR *.TXT /B /O:-D') DO NOTEPAD %%I & EXIT
EDIT:
#pam: you're right, I was assuming that the files were in date order, but you can change the command to:
FOR /F %%I IN ('DIR *.TXT /B /O:-N') DO NOTEPAD %%I & EXIT
then you have the file list sorted by name in reverse order.
Here you go... (hope no-one beat me to it...) (You'll need to save the file as lasttext.bat or something)
This will open up / run the oldest .txt file
dir *.txt /b /od > systext.bak
FOR /F %%i in (systext.bak) do set sysRunCommand=%%i
call %sysRunCommand%
del systext.bak /Y
Probably XP only. BEHOLD The mighty power of DOS.
Although this takes the latest filename by date - NOT by filename..
If you want to get the latest filename, change /od to /on .
If you want to sort on something else, add a "sort" command to the second line.
Use regular expression to parse the relevant integer out and compare them.