I would like to get a part of the current directory where my batch script is from.
The location is something like this : Y:\abc\def\ghi\jkl\script.bat
I just want to keep what's after Y:\abc\def\ (that is \ghi\jkl)
How to do this ?
I'm using the code below for getting the full path but how to make a delimitation ?
for /f %%a in ("%CD%") do set CURR=%%a
echo %CURR%
Thank you for your precious help.
Based upon your stated "directory where my batch script is from", the following should suffice, (the last line is added for demonstration purposes, please change it as necessary):
#Set "x=%~dp0"&SetLocal EnableDelayedExpansion
#Set "i=0"&Set "x!i!=%x:\="&Set /A i+=1&Set "x!i!=%"
#Set /A i-=1,y=i-1
#If %i% Lss 1 (Set "z=%x0%\")Else (If %i% Equ 1 (Set "z=%x0%\%x1%"
)Else Set "z=!x%y%!\!x%i%!")
#EndLocal&Set "y=%z%"
#Echo %x% becomes %y%&Pause
I have made it so that if the scripts directory isn't deep enough, the full path will still be output.
If you want to use the current directory instead of the scripts location, change %~dp0 on line 1 to %__CD__% or %CD%\ as needed.
I believe that maybe you could put the section to be cut inside a txt file and then manipulate the string from the loop in the file, like this:
echo %cd% > path.txt
for /f "tokens=3,* delims=\" %%a in (path.txt) do echo %%b
Determining the depth with the argument tokens=3 with the delimiter character being "\".
#echo off
setlocal
set "reversed="
set "fromdir=%~dp0"
for %%A in ("%fromdir:\=" "%") do call set "reversed=%%~A\%%reversed%%"
for /f "tokens=1-2 delims=\" %%A in ("%reversed%") do set "result=\%%B\%%A"
echo %result%
pause
If the path segments can be reversed, then getting the last 2 segments is a known number for setting the tokens option of 1-2 as they would become the 1st 2 segments. The 1st for loop does the reversing. The 2nd for loop gets the 1st 2 tokens and is set to result in reverse order, which is the original order.
The fromdir is set for the script directory %~dp0, though it can be set with %cd% if is wanted.
View set /? for how "%fromdir:\=" "%" does replacement of \ with " " so that the path segments become individual arguments i.e. "C:\dir1\dir2\dir3" becomes "C:" "dir1" "dir2" "dir3".
Can someone please help me understand command file syntax
IF "%INPUT_PATH%"=="" (
echo Searching for latest test results in: %TEST_RESULTS%
FOR /F "delims=" %%i in ('dir /O-D /B "%TEST_RESULTS%\*.trx"') DO (
SET INPUT_PATH=%TEST_RESULTS%\%%~ni
GOTO :DoneInputPath
) )
I get that it first checks if INPUT_PATH variable is empty and if it is empty then enters into an inner for loop, I am lost otherwise
specifically
FOR /F "delims=" %%i in ('dir /O-D /B "%TEST_RESULTS%\*.trx"')
SET INPUT_PATH=%TEST_RESULTS%\%%~ni
Most of the information you need is available in the built-in help, though it can be daunting if you are new to batch programming. For example, type HELP FOR or FOR /? from the command prompt to get help on the FOR command.
Explanation:
FOR /F "delims=" %%i in ('dir /O-D /B "%TEST_RESULTS%\*.trx"') ...
The DIR command lists all of the *.TRX files within the %TEST_RESULTS% path. The /B option gives the brief format (file names only). The /O-D option sorts the files by last modified date descending (newest first).
The FOR /F command has three modes, depending on the format of the IN() clause. The fact that the IN() clause is enclosed in single quotes means that FOR /F treats the contents as a command, and processes the output of the command, one line at a time. The "delims=" option means do not parse into tokens (preserve each entire line). So each line is iteratively loaded into the %%i variable. The %%i variable only exists within the context of the FOR command.
SET INPUT_PATH=%TEST_RESULTS%\%%~ni
I think you know what most of this command does. The only "unusual" aspect is the %%~ni syntax. That syntax expands the value of %%i into the base file name only, without any extension.
GOTO :DoneInputPath
The GOTO causes the FOR loop to abort after the first iteration. This means that INPUT_PATH will be set to the name of the most recently modified *.trx file, since it sorted to the top.
If the GOTO were not there, then the end result would be the oldest *.trx file instead.
try this, explanation is in the comment:
IF NOT DEFINED INPUT_PATH (
echo Searching for latest test results in: %TEST_RESULTS%
REM dir /OD means older files first and the youngest last, the last remains in INPUT_PATH; use "%%~nxi" for file name + file extension
FOR /F "delims=" %%i in ('dir /OD /B "%TEST_RESULTS%\*.trx"') DO SET "INPUT_PATH=%TEST_RESULTS%\%%~ni"
)
I have Asset tags embedded in BIOS. I use
wmic SYSTEMENCLOSURE get SMBiosAssetTag
This pulls the information I want but it is not formatted well:
SMBIOSAssetTag
11886
I need to just have those 5 numbers and nothing else. I will then use that variable to name the computer with a first logon script. I have spent hours on this, and I could have been done in 3 minutes if this was linux.
Note: I can't put linux tools on these builds :-(
Using
WMIC SYSTEMENCLOSURE GET SMBiosAssetTag /FORMAT:VALUE
will make a better output:
(some empty lines)
SMBIOSAssetTag=CZC1296FLD
(some empty lines)
So, in batch you may just
FOR /F "TOKENS=1,* DELIMS==" %%v IN (WMIC SYSTEMENCLOSURE GET SMBiosAssetTag /FORMAT:VALUE) DO IF /I "%%v" == "SMBIOSAssetTag" SET SMBIOSAssetTag=%%w
Side note: hard part in WMIC output is handling empty lines.
This will work, tested it myself:
for /f "eol=S" %%a in ('wmic SYSTEMENCLOSURE get SMBiosAssetTag^|sort') do (set var=%%a)
It works fine.
Mona
for /f "delims=" %%a in ('wmic SYSTEMENCLOSURE get SMBiosAssetTag') do for /f %%b in ("%%a") do set "var=%%b"
echo %var%
I am trying to parse the output of a command in a command line script. As a start i have to first capture the output of the command in a variable ( i guess) . So here is what i have written so far:
FOR /F "tokens=2* delims= " %%A IN ('wmic process where(name="javaw.exe") get commandline') DO SET VAR=%%B
echo %VAR%
where wmic process where(name="javaw.exe") get commandline is the command i want to execute and save the output.
But i get the following error upon executing this.
get was unexpected at this time
Any ideas why the error. And how do i proceed after storing the output in a variable. I am looking for a particular word say "XYZ" in the output and if that word is there i want to display a windows pop-up.
Thanks in advance for the help.
The reason it is giving you an error is because the first ) in the for loop is effectively ending the loop, then the get command is processed separately, which isn't recognised.
You need to use the caret ^ to escape the brackets and the =.
FOR /F "tokens=2* delims= " %%A IN ('wmic process where^(name^="javaw.exe"^) get commandline') DO SET VAR=%%B
Hope this helps
You need to change the syntax, but even then you will not get the desired results, as wmic normally responds with more than one line.
setlocal EnableDelayedExpansion
FOR /F "tokens=* delims=" %%A IN (
'"wmic process where(name="javaw.exe") get commandline"') DO (
set "line=%%A"
if "!line:XYZ=!" NEQ "!line!" (
echo The line contains XYZ
)
)
And setting delims to space will split the line at the first space, even if this is in the path of javaw.exe.
I would like to know how to loop through each line in a text file using a Windows batch file and process each line of text in succession.
I needed to process the entire line as a whole. Here is what I found to work.
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
The tokens keyword with an asterisk (*) will pull all text for the entire line. If you don't put in the asterisk it will only pull the first word on the line. I assume it has to do with spaces.
For Command on TechNet
If there are spaces in your file path, you need to use usebackq. For example.
for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
From the Windows command line reference:
To parse a file, ignoring commented lines, type:
for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do #echo %i %j %k
This command parses each line in Myfile.txt, ignoring lines that begin with a semicolon and passing the second and third token from each line to the FOR body (tokens are delimited by commas or spaces). The body of the FOR statement references %i to get the second token, %j to get the third token, and %k to get all of the remaining tokens.
If the file names that you supply contain spaces, use quotation marks around the text (for example, "File Name"). To use quotation marks, you must use usebackq. Otherwise, the quotation marks are interpreted as defining a literal string to parse.
By the way, you can find the command-line help file on most Windows systems at:
"C:\WINDOWS\Help\ntcmds.chm"
In a Batch File you MUST use %% instead of % : (Type help for)
for /F "tokens=1,2,3" %%i in (myfile.txt) do call :process %%i %%j %%k
goto thenextstep
:process
set VAR1=%1
set VAR2=%2
set VAR3=%3
COMMANDS TO PROCESS INFORMATION
goto :EOF
What this does:
The "do call :process %%i %%j %%k" at the end of the for command passes the information acquired in the for command from myfile.txt to the "process" 'subroutine'.
When you're using the for command in a batch program, you need to use double % signs for the variables.
The following lines pass those variables from the for command to the process 'sub routine' and allow you to process this information.
set VAR1=%1
set VAR2=%2
set VAR3=%3
I have some pretty advanced uses of this exact setup that I would be willing to share if further examples are needed. Add in your EOL or Delims as needed of course.
Improving the first "FOR /F.." answer:
What I had to do was to call execute every script listed in MyList.txt, so it worked for me:
for /F "tokens=*" %A in (MyList.txt) do CALL %A ARG1
--OR, if you wish to do it over the multiple line:
for /F "tokens=*" %A in (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)
Edit: The example given above is for executing FOR loop from command-prompt; from a batch-script, an extra % needs to be added, as shown below:
---START of MyScript.bat---
#echo off
for /F "tokens=*" %%A in ( MyList.TXT) do (
ECHO Processing %%A....
CALL %%A ARG1
)
#echo on
;---END of MyScript.bat---
#MrKraus's answer is instructive. Further, let me add that if you want to load a file located in the same directory as the batch file, prefix the file name with %~dp0. Here is an example:
cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
NB:: If your file name or directory (e.g. myfile.txt in the above example) has a space (e.g. 'my file.txt' or 'c:\Program Files'), use:
for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A
, with the type keyword calling the type program, which displays the contents of a text file. If you don't want to suffer the overhead of calling the type command you should change the directory to the text file's directory. Note that type is still required for file names with spaces.
I hope this helps someone!
The accepted answer is good, but has two limitations.
It drops empty lines and lines beginning with ;
To read lines of any content, you need the delayed expansion toggling technic.
#echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ text.txt"`) do (
set "var=%%a"
SETLOCAL EnableDelayedExpansion
set "var=!var:*:=!"
echo(!var!
ENDLOCAL
)
Findstr is used to prefix each line with the line number and a colon, so empty lines aren't empty anymore.
DelayedExpansion needs to be disabled, when accessing the %%a parameter, else exclamation marks ! and carets ^ will be lost, as they have special meanings in that mode.
But to remove the line number from the line, the delayed expansion needs to be enabled.
set "var=!var:*:=!" removes all up to the first colon (using delims=: would remove also all colons at the beginning of a line, not only the one from findstr).
The endlocal disables the delayed expansion again for the next line.
The only limitation is now the line length limit of ~8191, but there seems no way to overcome this.
Or, you may exclude the options in quotes:
FOR /F %%i IN (myfile.txt) DO ECHO %%i
Here's a bat file I wrote to execute all SQL scripts in a folder:
REM ******************************************************************
REM Runs all *.sql scripts sorted by filename in the current folder.
REM To use integrated auth change -U <user> -P <password> to -E
REM ******************************************************************
dir /B /O:n *.sql > RunSqlScripts.tmp
for /F %%A in (RunSqlScripts.tmp) do osql -S (local) -d DEFAULT_DATABASE_NAME -U USERNAME_GOES_HERE -P PASSWORD_GOES_HERE -i %%A
del RunSqlScripts.tmp
If you have an NT-family Windows (one with cmd.exe as the shell), try the FOR /F command.
The accepted anwser using cmd.exe and
for /F "tokens=*" %F in (file.txt) do whatever "%F" ...
works only for "normal" files. It fails miserably with huge files.
For big files, you may need to use Powershell and something like this:
[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }
or if you have enough memory:
foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" }
This worked for me with a 250 MB file containing over 2 million lines, where the for /F ... command got stuck after a few thousand lines.
For the differences between foreach and ForEach-Object, see Getting to Know ForEach and ForEach-Object.
(credits: Read file line by line in PowerShell )
Modded examples here to list our Rails apps on Heroku - thanks!
cmd /C "heroku list > heroku_apps.txt"
find /v "=" heroku_apps.txt | find /v ".TXT" | findstr /r /v /c:"^$" > heroku_apps_list.txt
for /F "tokens=1" %%i in (heroku_apps_list.txt) do heroku run bundle show rails --app %%i
Full code here.
To print all lines in text file from command line (with delayedExpansion):
set input="path/to/file.txt"
for /f "tokens=* delims=[" %i in ('type "%input%" ^| find /v /n ""') do (
set a=%i
set a=!a:*]=]!
echo:!a:~1!)
Works with leading whitespace, blank lines, whitespace lines.
Tested on Win 10 CMD