Searching for files but may need to time out - batch-file

I have a program to search drives for a specific file. The only problem is is that i wont know what drive it is on. The problem occurs when it searches a drive for a file that isn't there is there a way to go on to the next drive after say like 10 seconds. Heres my code so far
#echo off
setlocal EnableDelayedExpansion
set count=1
for /f "skip=1" %%a in ('wmic logicaldisk get caption') do (
set drive!count!=%%a
set /a count+=1
)
set "gh=!drive1!"
::Change this to do whatever with the variables
set "fh=!drive2!"
set "hh=!drive3!"
set "jh=!drive4!"
For /R %gh%\ %%G IN (*.ut2) do set jk="%%~dpG"
if defined jk (
echo %jk%
) else (
goto next
)
for /r %jk% %%a in (*) do if "%%~nxa"=="CTF-Hydro-16-2k3.ut2" set k=%%~dpnxa
if defined k (
echo %k% found
pause
cls
echo You have it
goto end
) else (
echo Map not found
copy %CD:~0,3%\Unrealmap\CTF-Hydro-16-2k3.ut2 %jk%
goto end
)
:next
For /R %fh%\ %%G IN (*.ut2) do set ht="%%~dpG"
if defined ht (
echo %ht%
) else (
goto there
)
for /r %ht% %%a in (*) do if "%%~nxa"=="CTF-Hydro-16-2k3.ut2" set m=%%~dpnxa
if defined k (
echo %m% found
pause
cls
echo You have it
goto end
) else (
echo Map not found
copy %CD:~0,3%\Unrealmap\CTF-Hydro-16-2k3.ut2 %jk%
goto end
:there
:end
cls
echo done
pause

#echo off
for /f "skip=1" %%D in ('wmic logicaldisk get caption') do (
for /r "%%D\\" %%G IN (*.ut2) do (
echo %%~dpG
if exist "%%~dpGCTF-Hydro-16-2k3.ut2" (
echo Found the map.
goto end
) else (
echo Map not found, copying
copy %CD:~0,3%\Unrealmap\CTF-Hydro-16-2k3.ut2 "%%~dpG"
goto end
)
)
)
:end
pause

Try next approach:
#ECHO OFF >NUL
SETLOCAL enableextensions
set /A "ii=0"
for /f "skip=1" %%D in ('
wmic logicaldisk get caption
') do for /F %%d in ("%%D") do (
echo searching %%d
for /F "delims=" %%G IN ('dir /B /S "%%d\CTF-Hydro-16-2k3.ut2" 2^>nul') do (
set /A "ii+=1"
set "k=%%G"
rem remove 'rem' from next line to discontinue searching
rem goto :testfound
)
TIMEOUT /T 10 /NOBREAK >NUL
)
:testfound
if %ii% EQU 0 (
echo Map not found
) else (
echo Map found %ii% times: last one "%k%"
)
Here the for loops against wmic command are
%%D to retrieve the caption value;
%%d to remove the ending carriage return in the value returned: wmic behaviour: each output line ends with 0x0D0D0A (<CR><CR><LF>) instead of common 0x0D0A (<CR><LF>).
See Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem
Another eventuality: parse
wmic datafile where "Extension='ut2' and FileName='CTF-Hydro-16-2k3'" get Name 2>NUL

Related

batch file: Parse string after substring occurence, not delimeter

I have and batch file script shows me output of adb utility.
FOR /F "skip=1 delims=~" %%x IN ('adb devices -l') DO echo %%x
2 output lines
0123456789ABCDEF device product:java_joyplus_qb7 model:TM702B4_3G device:java_joyplus_qb7 transport_id:12
F9NPFP084096 device product:WW_P023 model:P023 device:P023_1 transport_id:11
I want parse non-space substring after "transport_id:".
For the first line i want get 12, for second 11. How can I do that?
If I understand correctly what you've asked, the following batch-file should output the information you require.
#Echo Off
For /F "Skip=1 Tokens=1*" %%G In ('adb.exe devices -l') Do (Set "DI=%%H"
SetLocal EnableDelayedExpansion
For /F %%I In ("!DI:*transport_id:=!") Do EndLocal & Echo %%I)
Pause
And, if you wanted to do that from cmd:
For /F "Skip=1Tokens=1*" %G In ('adb.exe devices -l')Do #Set "DI=%H"&For /F %I In ('Cmd /D/V/C Echo "!DI:*transport_id:=!"')Do #Echo %~I
You may easily extract all variables no matter their positions and show what you want:
#echo off
setlocal EnableDelayedExpansion
FOR /F "skip=1 delims=" %%a IN ('adb devices -l') DO (
for %%b in (%%a) do for /F "tokens=1,2 delims=:" %%x in ("%%b") do set "%%x=%%y"
echo Product=!product!
echo Transport=!transport_id!
)
For example:
Product=java_joyplus_qb7
Transport=12
Product=WW_P023
Transport=11
SETLOCAL EnableDelayedExpansion
REM …
FOR /F "skip=1 delims=~" %%x IN ('adb devices -l') DO (
set "_ID="&set "_transport_id="
call :parse "" "%%~x"
echo transport_id !_transport_id! (!_ID!^)
)
REM … remaining part of your script here …
goto :eof
:parse
if "%~2"=="" goto :eof
for /F "tokens=1,*" %%G in ("%~2") do (
if "%~1"=="" (
set "_ID=%%~G"
call :parse "%%~G" "%%~H"
) else (
for /F "tokens=1,2 delims=: " %%g in ("%~2") do (
if /I "%%~g"=="transport_id" (
set "_transport_id=%%~h"
) else (
call :parse "%%~G" "%%~H"
)
)
)
)
goto :eof
Tested using the following script with hard-coded hypothetical adb output (not having adb installed):
#ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
(
REM last token
set "_ID="&set "_transport_id="
call :parse "" "0123456789ABCDEF device product:java_joyplus_qb7 model:TM702B4_3G device:java_joyplus_qb7 transport_id:12"
echo transport_id !_transport_id! (!_ID!^)
REM penult token
set "_ID="&set "_transport_id="
call :parse "" "F9NPFP084096 device product:WW_P023 model:P023 transport_id:11 device:P023_1"
echo transport_id !_transport_id! (!_ID!^)
REM elsewhere token
set "_ID="&set "_transport_id="
call :parse "" "abc123def567 transport_id:10 device product:XX_P023 model:P023 device:P023_2"
echo transport_id !_transport_id! (!_ID!^)
REM nowhere token
set "_ID="&set "_transport_id="
call :parse "" "noTransportId sport_id:10 device product:XX_P023 model:P023 device:P023_2"
echo transport_id !_transport_id! (!_ID!^)
)
goto :eof
:parse
if "%~2"=="" goto :eof
for /F "tokens=1,*" %%G in ("%~2") do (
if "%~1"=="" (
set "_ID=%%~G"
call :parse "%%~G" "%%~H"
) else (
for /F "tokens=1,2 delims=: " %%g in ("%~2") do (
if /I "%%~g"=="transport_id" (
set "_transport_id=%%~h"
) else (
call :parse "%%~G" "%%~H"
)
)
)
)
goto :eof
Output: D:\bat\SO\61588773.bat
transport_id 12 (0123456789ABCDEF)
transport_id 11 (F9NPFP084096)
transport_id 10 (abc123def567)
transport_id (noTransportId)

For Loop Ends Batch File Execution

My batch file is silently ending execution on the first loop (for /d "delims= eol=|" %%d in (*.*) do () and I can't tell why.
I'm not calling any other batch files
My subfolder names DO contain spaces, which I tried to handle with "delims= eol=|"
I never see !parent!!folder! echoed and it doesn't pause at the end. What am I doing wrong?
#Echo off
setlocal enabledelayedexpansion
pushd "%~dp0"
set "parent=%~dp0"
echo !parent!
set "destination=\\(test destination folder)\"
rem SET "destination=\\(prod destination folder)\"
set "FileCount=0"
for /d "delims= eol=|" %%d in (*.*) do (
set "folder=%%d"
echo !parent!!folder!
pause
for %%f in ("!parent!!folder!\(file identifying-pattern)*.DAT") do (
echo "File Type 1"
pause
if !FileCount! lss 200 (
set /a !FileCount!+=1
ECHO !FileCount!
ECHO !parent!!folder!%%f
ECHO !destination!%%f
MOVE "%%f" "!destination!"
)
(
for %%f in ("!parent!!folder!\(file identifying-pattern)*.DAT") do (
echo "File Type 2"
pause
if !FileCount! lss 200 (
set /a !FileCount!+=1
ECHO !FileCount!
ECHO !parent!!folder!%%f
ECHO !destination!%%f
MOVE "%%f" "!destination!"
)
)
)
for /d %%d in (*.*) do (
set "folder=%%d"
if not %%d==Archive (
if not %%d==Hold (
dir /b "!folder!"|find /v "">nul && ECHO "!folder! NOT EMPTY"||rmdir "!parent!!folder!"
)
)
)
pause
popd
I've took a guess at what you were doing, trying not to change the structure too much!
You'll need to add your destinations on lines 4 and 5 and your file patterns to lines 8 and 9 as necessary. (Please make sure you do not end your destination paths with back slashes):
#Echo Off
CD /D "%~dp0" 2>Nul || Exit /B
Set "Destination=\\(test destination folder)"
Rem Set "Destination=\\(prod destination folder)"
If Not Exist "%destination%\" Exit /B
Set "Pattern1=(file identifying-pattern)"
Set "Pattern2=(file identifying-pattern)"
Set /A Type1Count=Type2Count=0
SetLocal EnableDelayedExpansion
For /D %%A In (*) Do (
For %%B In ("%%A\%Pattern1%*.dat") Do (
Echo "File Type 1"
Set /A Type1Count +=1
If !Type1Count! Lss 200 (
Echo !Type1Count!. "%CD%\%%A\%%B" --^> "%Destination%\%%B"
If Not Exist "%Destination%\%%B\" MD "%Destination%\%%B"
Move /Y "%%B" "%Destination%\%%B">Nul
)
)
For %%C In ("%%A\%Pattern2%*.dat") Do (
Echo "File Type 2"
Set /A Type2Count +=1
If !Type2Count! Lss 200 (
Echo !Type2Count!. "%CD%\%%B\%%C" --^> "%Destination%\%%C"
If Not Exist "%Destination%\%%C\" MD "%Destination%\%%C"
Move /Y "%%C" "%Destination%\%%C">Nul
)
)
If /I Not "%%A"=="Archive" (
If /I Not "%%A"=="Hold" (
Set "file="
For %%D In (*) Do Set "file=1"
If Defined file (Echo %%A NOT EMPTY) Else RD "%%A" 2>Nul
)
)
)
Pause
If you're happy with it in your test you can Remark line 4 and unRemark line 5.

Batch scripting: read lines and execute a command after every other line read

Suppose I have a text file like this
node1.log
node2.log
node3.log
node4.log etc...
I want to read each line by line and execute
alan.exe node1.log node2.log
alan.exe node3.log node4.log
etc..
What is the best way to accomplish this?
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%a in (file.txt) do (
if not defined line (
set "line=%%a"
) else (
ECHO alan.exe !line! %%a
set "line="
)
)
Give this a try. File.txt will have your log file names.
#echo off
setlocal enabledelayedexpansion
FOR /F "delims=" %%G IN ('find /c /v "" ^<file.txt') DO SET NUM=%%G
SET /A NUM=NUM / 2
< file.txt (
FOR /L %%G IN (1,1,%NUM%) DO (
SET /P LINE1=
SET /P LINE2=
echo mypgm.exe !LINE1! !LINE2!
)
)
pause
Output
mypgm.exe node1.log node2.log
mypgm.exe node3.log node4.log
mypgm.exe node5.log node6.log
Press any key to continue . . .
Remove the word echo and replace mypgm.exe with the program you want to run. The echo is just in there for the proof of concept.
Like this:
#echo off
setlocal enabledelayedexpansion
set args=
set n=2
for /f "tokens=*" %%x in (file.txt) do (
set args=!args! %%x
set /a n -= 1
if !n! EQU 0 (
alan !args!
set args=
set n=2
)
)

Windows batch: How to remove last part of folders names

In a batch file I get a folder with a list of subfolders with an unknown number of underscores e.g.:
a_b_10
c_d_e_2
f_17
I need to remove the last token of the names i.e.
a_b
c_d_e
f
Thanks
You could try to get the last part with an underscore and then remove this from your string, but this only works when the last part is unique.
In your sample the last part seems to be always a number in spite of the other parts.
This uses the trick to parse parts of a string by replace the delimiter by a linefeed character.
#echo off
setlocal EnableDelayedExpansion
set LF=^
for /F "delims=" %%X in ('dir /b /AD') do (
call :removeLastPart "%%~X"
)
exit /b
:removeLastPart
set "str=%~1"
for %%L in ("!LF!") DO (
for /F "delims=" %%P in ("!str:_=%%~L!") do set "last=%%P"
)
echo The last part is '!last!'
REM ** now remove the last part by replacing with nothing **
set "str=!str:_%last%=!"
echo !str!
exit /b
#echo off
set "root_dir=C:\scriptests"
setlocal enableDelayedExpansion
for /f %%d in ('dir /b /a:d *_*') do (
call :lastindexof "%%d" _ lio
set "f_name=%%~d"
echo renaming !f_name!
for %%S in (!lio!) do ren !f_name! !f_name:~0,%%S!
)
endlocal
exit /b 0
:lastindexof [%1 - string ; %2 - find last index of ; %3 - if defined will store the result in variable with same name]
#echo off
setlocal disableDelayedExpansion
set "str=%~1"
set "splitter=%~2"
set LF=^
rem ** Two empty lines are required
setlocal enableDelayedExpansion
for %%L in ("!LF!") DO (
for /f "delims=" %%R in ("!splitter!") do (
set "var=!str:%%R=%%L!"
)
)
for /f delims^=^" %%P in ("!var!") DO (
set "last_part=%%~P"
)
if "!last_part!" equ "" if "%~3" NEQ "" (
echo "not contained" >2
endlocal
set %~3=-1
exit
) else (
echo "not contained" >2
endlocal
echo -1
)
call :strlen0.3 str strlen
call :strlen0.3 last_part plen
call :strlen0.3 splitter slen
set /a lio=strlen-plen-slen
endlocal & set lio=%lio%
endlocal & if "%~3" NEQ "" (set %~3=%lio%) else echo %lio%
exit /b 0
:strlen0.3 StrVar [RtnVar]
setlocal EnableDelayedExpansion
set "s=#!%~1!"
set "len=0"
for %%A in (2187 729 243 81 27 9 3 1) do (
set /A mod=2*%%A
for %%Z in (!mod!) do (
if "!s:~%%Z,1!" neq "" (
set /a "len+=%%Z"
set "s=!s:~%%Z!"
) else (
if "!s:~%%A,1!" neq "" (
set /a "len+=%%A"
set "s=!s:~%%A!"
)
)
)
)
endlocal & if "%~2" neq "" (set %~2=%len%) else echo **%len%**
exit /b
This solution will create the "renfolders.bat.txt" file for you to check in notepad, and run it as a batch file if you are happy with it.
This uses a helper batch file called repl.bat - download from: https://www.dropbox.com/s/qidqwztmetbvklt/repl.bat
Place repl.bat in the same folder as the batch file or in a folder that is on the path.
dir *_* /b /s /ad |repl ".*\\(.*)_.*" "ren \q$&\q \q$1\q" xa >"renfolders.bat.txt"
I just figured out this solution:
for /f %%f in ('dir /b /AD c:\MainFolder\') do (
set var=%%f
set var=!var:_= !
set /a count=0
for %%i in (!var!) do (set /a count+=1)
set /a count2=0
for %%i in (!var!) do (
set /a count2+=1
if /I !count2! equ 1 (set var2=%%i) else if not !count2! equ !count! (set var2=!var2!_%%i)
)
echo !var2!
)
Here is a novel approach
For each folder containing at least one _ in name:
create a temporary empty file with the same name
rename the temporary file, stripping off everything after the final _
read the new name into a variable
strip off the final _ from the name
For an explanation of how the rename works, see How does the Windows RENAME command interpret wildcards?
#echo off
setlocal enableDelayedExpansion
set "loc=%temp%\removeToken"
md "%loc%"
for /d %%F in (*_*) do (
copy nul "%loc%\%%F" >nul
ren "%loc%\*" "*_"
for %%A in ("%loc%\*") do set "new=%%~nxA"
del /q "%loc%\*"
echo old=%%F
echo new=!new:~0,-1!
echo(
)
rd "%loc%"
EDITED - Wrong copy of the code posted
It separates the elements of the directory name and iterates over them discarting the last element
#echo off
setlocal enabledelayedexpansion
for /d %%a in (*_*) do (
set "old=%%~na" & set "new=" & set "previous="
for %%b in ("!old:_=" "!") do (
if not defined previous (
set "previous=%%~b"
) else if not defined new (
set "new=!previous!"
) else set "new=!new!_!previous!"
set "previous=%%~b"
)
echo ren "%%~fa" "!new!"
)
endlocal

Editing an external batch config value with batch

I have a config file named config.conf with the content of:
[Config]
password=1234
usertries=0
allowterminate=0
I want to just edit the usertries value to 5, are there any batch script code that can help me do that
Thanks
This gets a little messy, but should work:
#echo off
set ConfigFile=config.conf
setlocal enabledelayedexpansion
(for /f "delims=" %%L in (%ConfigFile%) do (
set "LINE=%%L"
if "!LINE:~0,10!"=="usertries=" (echo usertries=5) else (echo !LINE!)
)) > %ConfigFile%.new
move /y %ConfigFile%.new %ConfigFile% > nul
Basically we're writing each line to a new file, unless it starts with usertries=. In which case we just insert our replacement line. Afterwards we move the new file on top of the old one to replace it.
#ECHO OFF
setlocal
::
:: set %1 to value %2 in config.conf
::
SET target=%2&IF NOT DEFINED target ECHO syntax is %0 keyname newvalue&GOTO :EOF
SET target=Config.conf
MOVE /y %target% %target%.old >NUL
FOR /f "tokens=1*delims==" %%i IN (%target%.old) DO (
IF /i %%i==%1 (ECHO %%i=%2) ELSE (
IF "%%j"=="" (ECHO %%i) ELSE (ECHO %%i=%%j)
)
) >>%target%
With this version, you can change an existing key to a value using
thisbatchname existingkey newvalue
I know I'm a little late to the party, but I decided to write a general purpose ini file utility batch script to address this question.
The script will let you retrieve or modify values in an ini-style file. Its searches are case-insensitive, and it preserves blank lines in the ini file. In essence, it allows you to interact with an ini file as a sort of very rudimentary database.
:: --------------------
:: ini.bat
:: ini.bat /? for usage
:: --------------------
#echo off
setlocal enabledelayedexpansion
goto begin
:usage
echo Usage: %~nx0 /i item [/v value] [/s section] inifile
echo;
echo Take the following ini file for example:
echo;
echo [Config]
echo password=1234
echo usertries=0
echo allowterminate=0
echo;
echo To read the "password" value:
echo %~nx0 /s Config /i password inifile
echo;
echo To change the "usertries" value to 5:
echo %~nx0 /s Config /i usertries /v 5 inifile
echo;
echo In the above examples, "/s Config" is optional, but will allow the selection of
echo a specific item where the ini file contains similar items in multiple sections.
goto :EOF
:begin
if "%~1"=="" goto usage
for %%I in (item value section found) do set %%I=
for %%I in (%*) do (
if defined next (
if !next!==/i set item=%%I
if !next!==/v set value=%%I
if !next!==/s set section=%%I
set next=
) else (
for %%x in (/i /v /s) do if "%%~I"=="%%x" set "next=%%~I"
if not defined next (
set "arg=%%~I"
if "!arg:~0,1!"=="/" (
1>&2 echo Error: Unrecognized option "%%~I"
1>&2 echo;
1>&2 call :usage
exit /b 1
) else set "inifile=%%~I"
)
)
)
for %%I in (item inifile) do if not defined %%I goto usage
if not exist "%inifile%" (
1>&2 echo Error: %inifile% not found.
exit /b 1
)
if not defined section (
if not defined value (
for /f "usebackq tokens=2 delims==" %%I in (`findstr /i "^%item%\=" "%inifile%"`) do (
echo(%%I
)
) else (
for /f "usebackq delims=" %%I in (`findstr /n "^" "%inifile%"`) do (
set "line=%%I" && set "line=!line:*:=!"
echo(!line! | findstr /i "^%item%\=" >NUL && (
1>>"%inifile%.1" echo(%item%=%value%
echo(%value%
) || 1>>"%inifile%.1" echo(!line!
)
)
) else (
for /f "usebackq delims=" %%I in (`findstr /n "^" "%inifile%"`) do (
set "line=%%I" && set "line=!line:*:=!"
if defined found (
if defined value (
echo(!line! | findstr /i "^%item%\=" >NUL && (
1>>"%inifile%.1" echo(%item%=%value%
echo(%value%
set found=
) || 1>>"%inifile%.1" echo(!line!
) else echo(!line! | findstr /i "^%item%\=" >NUL && (
for /f "tokens=2 delims==" %%x in ("!line!") do (
echo(%%x
exit /b 0
)
)
) else (
if defined value (1>>"%inifile%.1" echo(!line!)
echo(!line! | find /i "[%section%]" >NUL && set found=1
)
)
)
if exist "%inifile%.1" move /y "%inifile%.1" "%inifile%">NUL
Example:
C:\Users\me\Desktop>type config.conf
[Config]
password=1234
usertries=0
allowterminate=0
[Other]
password=foo
C:\Users\me\Desktop>ini /i usertries /v 5 config.conf
5
C:\Users\me\Desktop>ini /i usertries config.conf
5
C:\Users\me\Desktop>ini /s config /i password /v bar config.conf
bar
C:\Users\me\Desktop>ini /s other /i password /v baz config.conf
baz
C:\Users\me\Desktop>type config.conf
[Config]
password=bar
usertries=5
allowterminate=0
[Other]
password=baz

Resources