0

I'm trying to read the contents of a text file and store any paths found on each line into their own variable. There's just 1 path on each line and also on each line there's other text (double quotes, a number and a tab).

Is this even possible? I've spent around 6 hours scouring Bing and Google trying to find out if i can do this and i haven't found anything.

Here's an example of the text file:

"LibraryFolders"
{
  "1"       "D:\\Steam Games"
  "2"       "E:\\Steam Games"
}

The number of library folders listed and path of the library folder will be different for every user's computer.

Ruok2bu
  • 5
  • 3
  • It's possible. You can simulate an array with batch variables. That part is easy. Scraping paths might be tricky, but it's possible. Agree with Magoo though. Showing part of the file you wish to scrape would help. – rojo Dec 24 '14 at 01:23
  • I updated my question with the example file. – Ruok2bu Dec 24 '14 at 01:27

2 Answers2

3
@ECHO OFF
SETLOCAL
:: remove variables starting $
FOR  /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
FOR /f "tokens=1*" %%a IN (q27630202.txt) DO (
 IF "%%~b" neq "" SET "$%%~a=%%~b"
)
SET $

GOTO :EOF

I used a file named q27630202.txt containing your data for my testing.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • Awesome, many many thanks ;) One minor question though; what would the format be for each variable? – Ruok2bu Dec 24 '14 at 02:51
  • Each `$` variable would be a string format `D:\\Steam Games` – Magoo Dec 24 '14 at 03:09
  • What i mean though, what do i use for each variable (to pass on later in my batch file), i tried $1 but it doesnt output anything. – Ruok2bu Dec 24 '14 at 04:07
  • To access a batch variable, use `%var%` where `var` is the variable-name. Note that `"%var%"` is useful to pass as one entity a string (like for instance "D:\\Steam Games") which would be regarded as two strings `D:\\Steam` `Games` without the quotes. Spaces are the most common separators, but commasn and tabs can be used a separators too. The inverse of quoting a string is to strip the quotes, for which you use the `~` operator - so `%~1` for instance would mean 'the first parameter to the routine, quotes removed.' In your case, `"%$1%"` or `%$1%` would be required depending on desired result – Magoo Dec 24 '14 at 04:15
  • :O You are a god. All hail (Mr.) Magoo. – Ruok2bu Dec 24 '14 at 04:31
  • @Ruok2bu If Magoo's answer was helpful, please mark it as accepted. See [this page](http://meta.stackexchange.com/questions/5234/) for an explanation of why this is important. And welcome to Stack Overflow! – rojo Dec 24 '14 at 04:48
1

You know, that data file looks almost like JSON. Just for grins and giggles, I decided to load it into JScript, massage it into valid JSON, create a JScript object from it, then output the object values back into the batch script. It's not as efficient as Magoo's solution, but it was an entertaining exercise nevertheless.

@if (@a==@b) @end /* Harmless hybrid line that begins a JScript comment
@echo off
setlocal

set "JSON=json.txt"

for /f "delims=" %%I in ('cscript /nologo /e:JScript "%~f0" "%JSON%"') do (
    rem :: If you want to do stuff with each path returned,
    rem :: change "delims=" to "tokens=2 delims==" above.
    rem :: Then for each iteration of the loop, %%I will
    rem :: contain a path from the text file.
    set "%%I"
)

:: display all variables beginning with LibraryFolders
set LibraryFolders

goto :EOF

:: end batch / begin JScript */

var fso = new ActiveXObject('scripting.filesystemobject'),
    JSONfile = fso.OpenTextFile(WSH.Arguments(0), 1);

var JSON = JSONfile.ReadAll().split(/\r?\n/);
JSONfile.close();

// massage the data into valid JSON
for (var i=0; i<JSON.length; i++) {
    if (!i) JSON[i] += ':';
    else if (/^\s*(\"[^\"]+\"\s*){2}$/.test(JSON[i])) {
        JSON[i] = JSON[i].replace(/\"\s+\"/, '": "') + ',';
    }
}
JSON = JSON.join('').replace(/,\s*\}/, '}');

// create new object from now valid JSON text
eval('var obj = {' + JSON + '}');

// dump "var=val" out to be captured by batch for /f loop
for (var i in obj.LibraryFolders) {
    WSH.Echo('LibraryFolders['+i+']=' + obj.LibraryFolders[i]);
}
rojo
  • 24,000
  • 5
  • 55
  • 101