Looping .bat file with 2 changed variables - loops

Trying to automate some ScreamingFrog (SF) website crawls, which can be done via Command Line (CL). I've created a bat file that sets some variables, tells CL where the .exe is, and runs the relevant commands within SF:
set domain=http://example.com
set company=ExampleCom
set crawlResults=C:\Users\brand\Documents\ScreamingFrog\Crawls
set sf=C:\Program Files (x86)\Screaming Frog SEO Spider\
set configFile=C:\Users\brand\Documents\ScreamingFrog\setup\ConfigSchedule.seospiderconfig
chdir /d "%sf%"
ScreamingFrogSEOSpiderCli.exe --config "%configFile%" --crawl "%domain%" --save-crawl --task-name "%company%" --headless --output-folder "%crawlResults%" --google-drive-account "account#example.com" --export-format "gsheet" --bulk-export "Response Codes:Client Error (4XX) Inlinks,Response Codes:Server Error (5XX) Inlinks"
I could create a .bat file for every domain/company - however, I was wondering if I could instead loop the .bat and replace the %domain% and %company% with the next pair from a list?
Apologies for my lack of expertise, I really appreciate anyone who takes a peek.

(untested) The following should do fine:
#echo off
setlocal
set "crawlResults=C:\Users\brand\Documents\ScreamingFrog\Crawls"
set "sf=C:\Program Files (x86)\Screaming Frog SEO Spider\"
set "configFile=C:\Users\brand\Documents\ScreamingFrog\setup\ConfigSchedule.seospiderconfig"
chdir /d "%sf%"
for /f "skip=1 tokens=1,2 delims=;" %%a in (data.csv) do (
ECHO ScreamingFrogSEOSpiderCli.exe --config "%configFile%" --crawl "%%a" --save-crawl --task-name "%%b" --headless --output-folder "%crawlResults%" --google-drive-account "account#example.com" --export-format "gsheet" --bulk-export "Response Codes:Client Error (4XX) Inlinks,Response Codes:Server Error (5XX) Inlinks"
)
with contents of data.csv like:
Domain;Company
http://example.com;Example
http://guugle.com;Searcher
http://sellstuff.com;E-Shop
Remove the ECHO after verifying it does work as intended.

Related

getting syntax error when trying to run ren command

I am trying to build my software using cx_freeze for which I built a bat file that runs the build command so when the build is completed it generates build directory inside which there is another directory exe.win-amd64-3.6 containing the bundled code. inside which there is lib/scipy/spatial/cKDTree.cp36-win_amd64.pyd now this file has to be renamed as ckdtree.cp36-win_amd64.pyd for the build to run. I am trying to automate this by including rename in batch file but it's giving error.
I am trying to run rename command when build is completed but it's not working i get the error the syntax is incorrect. i tried to remove
%~dp0
even this didn't work
#ECHO OFF
Set "FRAS_Folder=%~dp0build_logs\FRAS"
If Not Exist "%FRAS_Folder%" MD "%FRAS_Folder%"
Call :Gen_Report_Name fras_logname
echo FileName : "%fras_logname%"
echo Absolute PathName : "%FRAS_Folder%\%fras_logname%"
REM Example save the result of this command with a log file into this folder
python setup.py build>"%FRAS_Folder%\%fras_logname%"
#REM rename the scipy.spatial.cKDtree file to scipy.spatial.ckdtree in lib/scipy/spatial
#REM rename the file cKDTree.cp36-win_amd64.pyd to ckdtree.cp36-win_amd64.pyd in lib/scipy/spatial
ren "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\cKDTree.cp36-win_amd64.pyd" "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\ckdtree.cp36-win_amd64.pyd"
pause & exit /b
:::::::::::::::::: FUNCTION :::::::::::::::::::
:Gen_Report_Name <file_with_date to be set>
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set "dt=%%a"
set datestamp=%dt:~0,8%
set timestamp=%dt:~8,6%
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 "stamp=%YYYY%%MM%%DD%_%HH%%Min%%Sec%"
Set "%1=%stamp%.log"
Exit /b
::------------------------------------------------------------------------------------
Kindly help me figure what's the issue!
You are using the wrong syntax for the ren command. See ren /?
The second filename must be a filename without path.
If you prefer to include the path for the second filename use the move command.
Windows is case insensitive so the files are having the same name. You will need to use an intermediate filename to change the case of the filename.
Try this:
ren "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\cKDTree.cp36-win_amd64.pyd" "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\ckdtree.cp36-win_amd64.tmp"
ren "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\ckdtree.cp36-win_amd64.tmp" "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\ckdtree.cp36-win_amd64.pyd"

Am I the only one who have this problem: While running something like .bat, the "X:\..\..path" often becomes ""X:\..\path and producing errors?

While running something like .bat, the "X:\..\..path" often becomes ""X:\..\path and producing errors. For example, I was installing apktool, then it just appeared this:
'""C:\Program' is not recognized as an internal or external command,
operable program or batch file.
I then copy the command and put one of the double quote to the end, which is like this: "C:\Program"
And everything just went smoothly, installation was successful. Then I tried to decode an apk, and the exactly same problem occurred: '""C:\Program' is not recognized as an internal or external command, operable program or batch file. This time I have no idea how to fix it, it's not like the .bat now, I cannot get the #echo on and copy the last command and edit it. So I am here to ask: If I am the only one who met this? Any way to fix this? Thank you.
My command:
apktool d test.apk
Image of running a decode command : 1
apktool.bat content:
#echo off
setlocal
set BASENAME=apktool_
chcp 65001 2>nul >nul
set java_exe=java.exe
if defined JAVA_HOME (
set java_exe="%JAVA_HOME%\bin\java.exe"
)
rem Find the highest version .jar available in the same directory as the script
setlocal EnableDelayedExpansion
pushd "%~dp0"
if exist apktool.jar (
set BASENAME=apktool
goto skipversioned
)
set max=0
for /f "tokens=1* delims=-_.0" %%A in ('dir /b /a-d %BASENAME%*.jar') do if %%~B gtr !max! set max=%%~nB
:skipversioned
popd
setlocal DisableDelayedExpansion
rem Find out if the commandline is a parameterless .jar or directory, for fast unpack/repack
if "%~1"=="" goto load
if not "%~2"=="" goto load
set ATTR=%~a1
if "%ATTR:~0,1%"=="d" (
rem Directory, rebuild
set fastCommand=b
)
if "%ATTR:~0,1%"=="-" if "%~x1"==".apk" (
rem APK file, unpack
set fastCommand=d
)
:load
"%java_exe%" -jar -Duser.language=en -Dfile.encoding=UTF8 "%~dp0%BASENAME%%max%.jar" %fastCommand% %*
rem Pause when ran non interactively
for /f "tokens=2" %%# in ("%cmdcmdline%") do if /i "%%#" equ "/c" pause
Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \, Space or " - build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value" is used, then the quotes become part of the value assigned.
set java_exe="%JAVA_HOME%\bin\java.exe"
Should be
set "java_exe=%JAVA_HOME%\bin\java.exe"
(apply this principle throughout your code)
Then, if you require " anywhere, insert it where it's needed - don't try to include it as part of a variable's value.
This should clean up at least some of your problems.

Batch File - Get filename from directory and save as variable

I am trying to read in a directory and get the filename from that directory.
I then want to save the filename as a variable and echo that filename out.
Here is the code I am using:
for /F %%a in ('dir C:\Users\username\Documents\Training\Pentaho\Outputs\BatchFileOutput\ *.csv') do set FileName=%%a
echo %FileName%
I am getting the following when command prompt runs:
"File not found
Directory"
Does anyone know how to resolve this or where I'm going wrong?
Thanks
Safer way of doing the same:
#echo off
setlocal
set "yourDir=C:\Users\username\Documents\Training\Pentaho\Outputs\BatchFileOutput\"
set "yourExt=*.csv"
pushd %yourDir%
for %%a in (%yourExt%) do echo %%a
popd
endlocal
Sets both: Your directory and the extension you are searching for, Changes the directory to the one previously setted possibly including a /drive change and then runs a loop over all files matching your extension and echo them out. To save only the last one you can use:
...do set fileName=%%a
echo %FileName%
Or to use them all within the loop you can use:
#echo off
Setlocal EnableDelayedExpansion
REM Other things done here
do (
REM Do stuff with %%a here
Set filename=%%a
echo !filename!
echo !filename:~0,6!
echo !filename:a=b!
)
If you just want to echo them, you can just go for echo %%a. If you want to do other things like string-substitution or substrings as described in the comments you need DelayedExpansion as shown above. There are a lot of questions on SO as well.
Note that you can get different "parts" of the path of your file. Have a look on this answer I always have a look on as well. Alternatively check the documentation for the for command typing for /? into the command-line.

CMD trying to set variable in a loop

I'm working with windows' cmd and trying to set a variable in a loop. Here's the code I have:
for /d %%a in ("F:\backup*") do set folder=%%a
ECHO %folder%
PAUSE
I want to look for a folder with name starting with "backup" on drive F and save that folder's name to %folder% variable. So for example if the folder would be called "backup 2017-01-18" I'd like that saved to a var.
Instead it doesn't seem to set anything as the ECHO just prints that "ECHO is on". The for loop is correct and the folder is there as well (I'm already using that piece of code for other batch with robocopy).
I could theoretically put all my code inside the FOR loop and use %%a instead of the %folder% var but that seems like a hacky solution.
All the solutions I found so far pointed to using EnableDelayedExpansion. I modified the code to use it like that:
Setlocal EnableDelayedExpansion
for /d %%a in ("F:\backup*") do set folder=%%a
ECHO !folder!
PAUSE
But now ECHO prints "!folder!" as if it would not detect the variable. If I revert to ECHO %folder% I once again learn that "ECHO is on".
EDIT:
I found the issue here. I was also running another batch file on the backup folder. It turns out that ROBOCOPY (which I used in that batch) is setting the enclosing folder to hidden, system and readonly by default (even if copied files are not hidden or system o_0). When I removed HSR attributes on the directory the code posted here started working fine (the initial version).
If your loop for /d %%a in ("F:\backup*") do does not detect any directories whose names begin with backup, they either do not exist or there are the attributes hidden and/or system set.
To detect also such hidden or system directories, replace the for /D loop by this:
rem Change to parent directory "F:\" temporarily in order for the `~f` modifier to resolve the full path properly:
pushd "F:\" || exit /B 1
for /F "eol=| delims=" %%D in ('dir /B /A:D /O:N "backup*"') do set "folder=%%~fD"
popd

How to run several shortcuts (.lnk files) with a script in Windows?

I’m trying to create a script to run all the tools I use working in a particular project (dor instance, gulp, phpstorm, php server, etc.)
I’d like to run shortcuts but not executable files. I can see two possible ways to achieve it in Windows:
VbScript
cmd.exe
Unfortunately, I’ve failed both:
1) WshShell fire .lnk file and I can't find an alternative way to do that:
To do so I’m trying to write .cmd file or .vbs
However, I’ve got the problem in each way.
Dim WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "notepad.exe" ' Works alright
WshShell.Run "C:\Users\eugene\Desktop\gulp EngMe.lnk" ' got an Exception: Unknown Exception
2) .cmd script waits for closing previously started app:
#rem urls and filesystem shortcuts start alright:
"C:\Users\eugene\Desktop\8000.url"
"C:\Users\eugene\Desktop\project_folder.lnk"
#rem the following two commands are starting sequentially, when the previous one has closed.
"notepad.exe"
#rem shortcut to %windir%\system32\notepad.exe:
"C:\Users\eugene\Desktop\Notepad_.lnk"
What I'm doing wrong and is there another way to do what I'm trying?
Paths with spaces must be "quoted" when fed to .Run so:
WshShell.Run """C:\Users\eugene\Desktop\gulp EngMe.lnk"""
Will work fine.
Try using powershell for scripting.
Look at the question - Execute shortcuts like programs
Look at Mark Schill's answer using invoke-item to launch .lnk files like programs.
This is probably your best way to address your script challenges.
You can check the shortcutjs.bat which is capable to read a .lnk file properties. With this you will execute all .lnk files in the current directory in the correct working directory:
#echo off
for %%# in (*.lnk) do (
call :executeShortcut "%%#"
)
exit /b %errorlevel%
:executeShortcut - %1 - shortcut to execute
setlocal enableDelayedExpansion
for /f "tokens=1,* delims=:" %%a in ('call shortcutjs.bat -examine %1') do (
if /i "%%a" equ "Target" (
set "target=%%b"
set "target=!target:~1!"
)
if /i "%%a" equ "Working Directory" (
set "workdir=%%b"
set "workdir=!workdir:~1!"
)
)
start "%target%" /d "%workdir%" /wait /b "%target%"
exit /b %errorlevel%

Resources