views:

201

answers:

5

Hello All,

I am trying to read some info from a text file by using windows command line, and save it to a variable just like "set info =1234"

Below is the content of the txt file, actually I just need the revision number, and the location of it is always the same line 5, and from column 11 to 15. In the sample it's 1234, and I am wondering is there a way to save it to a variable in Dos command line.

Thanks a lot!

svninfo.txt:

Path: .
URL: https://www.abc.com
Repository Root: https://www.abc.com/svn
Repository UUID: 12345678-8b61-fa43-97dc-123456789
Revision: 1234
Node Kind: directory
Schedule: normal
Last Changed Author: abc
Last Changed Rev: 1234
Last Changed Date: 2010-04-01 18:19:54 -0700 (Thu, 01 Apr 2010)
+4  A: 

The following code snippet shows how to do this:

@echo off
setlocal enableextensions enabledelayedexpansion
set revision=
for /f "delims=" %%a in (input.txt) do (
    set line=%%a
    if "x!line:~0,10!"=="xRevision: " (
        set revision=!line:~10!
    )
)
echo !revision!
endlocal

Its output is 1234 as desired.

The setlocal is what I use in every script to ensure variables are treated in a known way. The for statement processes each line in the input file (the delims bit stops the line from being tokenised into separate words).

The !line:~ bits are substrings with !line:~0,10! being the first ten characters and !line:~10! being the rest.

So, basically, it checks every line to see if it starts with "Revision: " and, if so, extracts the rest of the line for later.

paxdiablo
Thanks a lot! It works.
Ray
I'd personally go with the `findstr` variant, though. Makes the intent a lot clearer and is a little shorter since you don't have to check the start of the line with substrings.
Joey
It has been a while, but IIRC I like to put `@SETLOCAL` on the first line, so the `@ECHO OFF` doesn't affect the echo setting of a calling script. Also, I like to replace the `@ECHO OFF` with `@IF NOT DEFINED _ECHO ECHO OFF`, so I can use `SET _ECHO=1` to debug my scripts.
Jay Bazuzi
+2  A: 

Use the for command to parse the file:

for /f "skip=4 tokens=2" %%l in (svninfo.txt) do (
    set revision=%%l
    goto gotrev
)

:gotrev
echo revision is %revision%
Dan Story
Pretty succint this one! :)
Leniel Macaferi
Succinct, yes, but paxdiablo's version is probably a better choice, since it actually checks the data it's going to return for conformity instead of just relying on a line number.
Dan Story
+1  A: 

if you have can use GNU tools, such as gawk

@echo off
for /F %%a in ('gawk -F":" "$1~/Revision/{print $2}" file') do (
        set var=%%a
)
echo %var%
ghostdog74
+4  A: 

Here's a one line version:

for /f "tokens=2" %%i in ('findstr Revision: input.txt') do set revision=%%i
  1. findstr is used to filter the file. It will print "input.txt:Revision: 1234"
  2. Then the "tokens=2" means that we are interested in the second token, "1234". By default for breaks on white space.
shf301
Very clever! I'd forgotten about findstr.
Dan Story
To add to this: You should probably use a regular expression match and anchor the `Revision:` string to the start of the line. You'll never know whether it might not appear in other places as well :-)
Joey
@Johannes wants you to use `fidnstr /R` to enable regex.
Jay Bazuzi
+1  A: 

Knowing how to use CMD scripting deftly is great, but using PowerShell is even better. Here's one way to do it:

$revision = (( gc .\svninfo.txt | ? { $_.StartsWith( 'Revision: ' ) } ) -split ' ')[1]

What's going on?

$revision is a variable

gc is Get-Content, aka type. Each line in the file becomes a string in a sequence (pipeline).

? is Where-Object. It filters the objects in a pipeline based on a condition.

{} delimits a script block

$_ is the current object in the pipeline.

-split invokes String.Split() in .NET, giving you an array of objects

[1] indexes in to the array

Jay Bazuzi