DName
DName

Reputation: 23

INI file get section line by line

I have an ini file like this:

[section1]
line1
line2
[section2]
line3
line4

I want to read lines, but only from [section1] for example. I need only the line1 and line2 as string. Now it is running:

SET var=lines.txt
FOR /F "tokens=*" %%a in (%var%) DO (
    CALL script.cmd %%a
)

It is a batch file, but I can't find a solution. Every time when I want to use contents from section2, I need to use lines2.txt, but now I merged together (ini file above).

Upvotes: 2

Views: 1245

Answers (4)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200453

I would recommend parsing the INI file properly, e.g. like this:

$inifile = 'C:\path\to\your.ini'
$ini = @{}

Get-Content $inifile | ForEach-Object {
  $_.Trim()
} | Where-Object {
  $_ -notmatch '^(;|$)'
} | ForEach-Object {
  if ($_ -match '^\[.*\]$') {
    $section = $_ -replace '\[|\]'
    $ini[$section] = @{}
  } else {
    $key, $value = $_ -split '\s*=\s*', 2
    $ini[$section][$key] = $value
  }
}

Then you can access the elements of section1 like this:

$ini['section1']['line1']

or (using dot-notation) like this:

$ini.section1.line1

You can also enumerate all elements of a section like this:

$ini['section1'].Keys
$ini['section1'].Values

or like this:

$ini['section1'].GetEnumerator()

Upvotes: 1

npocmaka
npocmaka

Reputation: 57282

If your ini file is with valid format this will set all lines in the wanted section in a list of variables starting with [section1]. It will handle comments also and will perform left trim on the lines.Uses only cmd internal commands so should be fast.

@echo off

setlocal EnableDelayedExpansion
set "file=test.ini"
set "section=[section1]"

set flag=0
for /f "usebackq delims=" %%# in ("%file%") do (
    set line=%%#
    ::trim
    for /f "tokens=* delims= " %%a in ("!line!") do set "line=%%a"
    set f=!line:~0,1!
    if "!f!" neq ";" (
        if !flag! equ 1 (
            for /f "tokens=1* delims==" %%a in ("!line!") do (
            ::for /f "tokens=1* delims==" %%a in ("%%#") do (
                set "!section!.%%a=%%b"
            )
        )

        if "!f!" equ "[" (
            if "!line!" equ "%section%" (
                set flag=1
            ) else (
                set flag=0
            )
        )       
    )
)

set %section%.

Upvotes: 0

Martin Brandl
Martin Brandl

Reputation: 58991

In PowerShell you could use this two read the first two lines from the section1:

$content = Get-Content "Your_Path_here"
$section1Start = $content | Where-Object { $_ -match '\[section1\]'} | select -ExpandProperty ReadCount
$content | Select -Skip $section1Start -First 2

Upvotes: 1

Stephan
Stephan

Reputation: 56208

use a flag to toggle action (set the flag when the starting header is found, unset it, when the next header starts):

@echo off
set var=test.ini
set "flag="
FOR /F "tokens=*" %%a in (%var%) DO (
  if defined flag (
     echo %%a|find "[" >null && set "flag=" || (
       echo calling script.cmd with parameter %%a
     )
  ) else (
    if "%%a" == "[section1]" set flag=1
  )
)

Upvotes: 1

Related Questions