11

I am trying to get '6' out of the java version output given below

java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b07)
Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)

For the same I wrote this batch script

set VERSION6="1.6.0_21"
java -version 2>&1 | findstr "version" >ab.txt
for /f "tokens=3" %%g in (ab.txt) do (
  if not %%g == %VERSION6% echo %%g
  echo %%g
)

%%g displays "1.6.0_21"

May someone guide me to correct direction? I am not much familiar with for /f.

Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
AabinGunz
  • 12,109
  • 54
  • 146
  • 218

4 Answers4

13
@echo off
setlocal

set VERSION6="1.6.0_21"
for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do (
    @echo Output: %%g
    set JAVAVER=%%g
)
set JAVAVER=%JAVAVER:"=%
@echo Output: %JAVAVER%

for /f "delims=. tokens=1-3" %%v in ("%JAVAVER%") do (
    @echo Major: %%v
    @echo Minor: %%w
    @echo Build: %%x
)

endlocal

In the first for loop, "tokens=3" says that we're going to just use the third token from the command output. Rather than redirect the output of the java -version command to a file, we can run this command within the for loop itself. The carets (^) are escape characters, and are needed so we can embed the >, & and | symbols in the command string.

Within the body of the for loop, we set a new var, JAVAVER, so that we can do some manipulation of the version string later.

The set JAVAVER=%JAVAVER:"=% command removes the double quotes from around the version string.

The last for loop parses the java version string. delims=. says we're going to delimit tokens using periods. tokens=1-3 says we're going to pass the first three tokens from the string to the body of the loop. We can now get the components of the java version string using the explicit variable, %%v and the implied variables (next letters in the alphabet) %%w and %%x.

When I run this on my system I get:

Output: "1.6.0_24" 
Output: 1.6.0_24
Major: 1 
Minor: 6 
Build: 0_24
Patrick Cuff
  • 28,540
  • 12
  • 67
  • 94
  • Thanks Patrick, that was really cool stuff. Wish i'll write my own someday, but this for /f is pretty confusing for me :( – AabinGunz Apr 15 '11 at 12:08
  • There is one more thing I needed to ask related to the above question. If my JAVA_HOME path is set to "c:\Program Files\...." and when I run the script it gets a space and says "'C:\Program' is not recognized as an internal or external command, operable program or batch file." How can I overcome this issue? – AabinGunz Apr 19 '11 at 09:55
  • 1
    @Abhishek, try putting double quotes around `%JAVA_HOME%`, like this: `"%JAVA_HOME%"`. – Patrick Cuff Apr 19 '11 at 14:49
  • Please take a look at a similar question http://stackoverflow.com/questions/7550844/identify-if-java-cannot-be-executed-in-widows-batch-script – AabinGunz Sep 26 '11 at 05:28
  • 1
    @Patrick Cuff what if the java executable within the code (line 4) is derived from a variable: `for /f "tokens=3" %%g in ('%JAVA_HOME% -version 2^>^&1 ^| findstr /i "version"')` - in such cases, how can I specify quotes? Just using quotes around JAVA_HOME does not seem to work! – Neel May 28 '13 at 16:52
  • 1
    @Neel try adding %JAVA_HOME% (just the bin directory) to the front of the PATH (you have setlocal specified so it is only valid for the scope of the bat file). `SET PATH=%JAVA_HOME%\bin;%PATH%'` `for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"')` etc – shonky linux user Sep 17 '14 at 03:46
  • Small clarification to the last comment based on https://superuser.com/a/940139/459204: to add JAVA_HOME to PATH, use `set "PATH=%JAVA_HOME%\bin;%PATH%"` – Alexander Udalov Jan 08 '21 at 13:22
4

I've made some modification to Patrick's answer so it works with Java 9, 10, etc. This returns minor version for 1.x, and major version for Java 9, 10, etc.

@echo off
setlocal

rem We use the value the JAVACMD environment variable, if defined
rem and then try JAVA_HOME
set "_JAVACMD=%JAVACMD%"
if "%_JAVACMD"=="" (
  if not "%JAVA_HOME%"=="" (
    if exist "%JAVA_HOME%\bin\java.exe" set "_JAVACMD=%JAVA_HOME%\bin\java.exe"
  )
)
if "%_JAVACMD%"=="" set _JAVACMD=java

rem Parses x out of 1.x; for example 8 out of java version 1.8.0_xx
rem Otherwise, parses the major version; 9 out of java version 9-ea
set JAVA_VERSION=0
for /f "tokens=3" %%g in ('%_JAVACMD% -Xms32M -Xmx32M -version 2^>^&1 ^| findstr /i "version"') do (
  set JAVA_VERSION=%%g
)
set JAVA_VERSION=%JAVA_VERSION:"=%
for /f "delims=.-_ tokens=1-2" %%v in ("%JAVA_VERSION%") do (
  if /I "%%v" EQU "1" (
    set JAVA_VERSION=%%w
  ) else (
    set JAVA_VERSION=%%v
  )
)

@echo %JAVA_VERSION%

endlocal

echoes 8 or 17 etc.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
1
for /f tokens^=2-5^ delims^=.-_+^" %j in ('java -fullversion 2^>^&1') do @set "jver=%j%k%l%m"

This will store the java version into jver variable and as integer And you can use it for comparisons .E.G

if %jver% LSS 16000 echo not supported version

.You can use more major version by removing %k and %l and %m.This command prompt version.

For .bat use this:

@echo off
PATH %PATH%;%JAVA_HOME%\bin\
for /f tokens^=2-5^ delims^=.-_+^" %%j in ('java -fullversion 2^>^&1') do set "jver=%%j%%k%%l%%m"

According to my tests this is the fastest way to get the java version from bat (as it uses only internal commands and not external ones as FIND,FINDSTR and does not use GOTO which also can slow the script). Some JDK vendors does not support -fullversion switch or their implementation is not the same as this one provided by Oracle (better avoid them).

npocmaka
  • 55,367
  • 18
  • 148
  • 187
1

This will extract the minor part of the version number:

java -version 2>&1 | awk '/version/ {print $3}' | awk -F . '{print $2}'

However, it may be better to extract the major.minor and match on that in case Oracle ever change the version number scheme again e.g.:

java -version 2>&1 | awk '/version/ {print $3}' | egrep -o '[0-9]+\.[0-9]+'
Owen Fraser-Green
  • 777
  • 1
  • 11
  • 14
  • 1
    Hey Thanks Owen. awk does not work on windows, I used the same in linux, but yours seem better here is mine java -version 2>&1 | head -1 | awk '{print $NF}' | cut -d'.' -f2 – AabinGunz Apr 15 '11 at 11:08
  • Ah, my bad. Sorry, I didn't read closely enough to notice it was Windows. – Owen Fraser-Green Apr 15 '11 at 11:12
  • It's ok and it seems I need 15 reputation to vote up. I am new to this site, will do it when I have enough reputation on this site. Thanks again! – AabinGunz Apr 15 '11 at 11:16
  • Save it for Patrick who answered the question you actually asked :) – Owen Fraser-Green Apr 15 '11 at 11:20
  • On Windows you can also use PowerShell to do something similar: `$a = [regex]::matches((java -version 2>&1),"[0-9]\.[0-9]\.[0-9]_[0-9]{2}")[1].value; $a.split(".")`. You can access the version components by their index; [0] = major, [1] = minor, [2] = build. – Patrick Cuff Apr 16 '11 at 13:17