Edit text within an .ini file Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Lem2001
Posts: 127
Joined: 27 Jun 2017, 17:59

Edit text within an .ini file

18 Oct 2019, 16:00

How would I go about editing and ini file to partially remove some of its contents (between two section headers)?

For example, if I had a file called settings.ini and within this file was sections (each one enclosed in square brackets) something like this:

Code: Select all

[Preferences]
color=#ff00ee
size=34
etc.
[Recent]
seiejdieef
runjowoeud
rrudisjsuw
[Bookmarks]
What AHK commands would I use to delete whatever text is between 'Recent' and 'Bookmarks' sections (not matter how many lines) and leave just 3 blank lines between the two section headers, and then save the file?

I've never used AHK to do anything within a file itself before, so I want to make sure that I get it right and not accidentally delete other important settings in the .ini file.

Thanks
AHKStudent
Posts: 1472
Joined: 05 May 2018, 12:23

Re: Edit text within an .ini file

19 Oct 2019, 02:01

AHK has commands to work with ini files but the way ini files work there are no blank lines when you remove a key. You can read about the main ini commands (read, write and delete) in the documentation https://www.autohotkey.com/docs/commands/IniRead.htm

Here is some code that can do what you want, maybe someone can post a better way. Always backup the files I did not test the code well.

Code: Select all

FileName := "inidata.ini"
FileRead, t, % FileName
cInd = 99999 ; very bad practice 
cIndend = 99999 ; very bad practice 
Loop, Parse, t, `n
{
	If InStr(A_LoopField, "[Recent]")
		cInd := A_Index 
	If InStr(A_LoopField, "[Bookmarks]")
		cIndend := A_Index
	If ((A_Index > cInd) && (A_Index < cIndend)) {
		NF .= "`n"
	}
	Else {
		NF .= A_LoopField "`n"
	}
}
MsgBox, % NF
Odlanir
Posts: 659
Joined: 20 Oct 2016, 08:20

Re: Edit text within an .ini file

19 Oct 2019, 06:19

Two ways, I think the first is the most reliable.

Code: Select all

FileDelete, TestINI_New.ini
FileRead, AllFile, TestINI.ini
FileAppend, % RegExReplace(AllFile, "`amsU)(?<=\[Recent\])(.*)(?=\[)","`n`n`n$2"), TestINI_New.ini
run, TestINI_New.ini
;~ FileMove,TestINI_New.ini, TestINI.ini, 1 ; <----- Replace your original ini file
ExitApp

Code: Select all

IniRead, AllSection ,TestINI.ini, Recent
allRecentKeys := Object(StrSplit(RegExReplace(AllSection ",1","`n",",1,"),",")*), Count := 0
FileDelete, TestINI_New.ini
Loop, read, TestINI.ini, TestINI_New.ini
{   
   If !(allRecentKeys.Haskey(A_LoopReadLine))
      FileAppend, %A_LoopReadLine%`n
   else if ( ++Count <= 3) { ; write max 3 blank lines in Recent section
      FileAppend, % " `n"
   }
}
run, TestINI_New.ini
;~ FileMove,TestINI_New.ini, TestINI.ini, 1 ; <----- Replace your original ini file
____________________________________________________________________________
Windows 10 Pro 64 bit - Autohotkey v1.1.30.01 64-bit Unicode
Lem2001
Posts: 127
Joined: 27 Jun 2017, 17:59

Re: Edit text within an .ini file

20 Oct 2019, 10:27

Thank you both for your replies.

Odlanir, your first example was the one I ended up using. It is very clean and elegant (and works well). I could not have figured this out for myself (Regex is not my strong point).

There is just one problem with it; the method that you've used for detecting the next header section is simply the next appearance of a square bracket.

This means that any 'recent data' that includes square brackets causes the script to stop short of deleting anything after that.

Question:

Is it possible to amend the Regex to detect the next instance of a line that starts and ends with square brackets (i.e. no characters or spaces before or after the square brackets on that line). This would seem to be a more reliable detection method, without having to hard-code the actual ini section name (which would cause havoc if the sections ever changed order).

Thanks
Odlanir
Posts: 659
Joined: 20 Oct 2016, 08:20

Re: Edit text within an .ini file  Topic is solved

20 Oct 2019, 11:56

This should work:

Code: Select all

FileDelete, TestINI_New.ini
FileRead, AllFile, TestINI.ini
FileAppend, % RegExReplace(AllFile, "`amsU)(?<=\[Recent\])(.*)(?=^\[\w+]$)","`n`n`n$2"), TestINI_New.ini
run, TestINI_New.ini
Tested with this sample ini:
[Preferences]
color=#ff00ee
size=34
etc.
[Bookmarks]
kk=10
ss=20
jj=30
[Recent]
sei[braketopen
runjowoeud
[]
aaa[inside]dadad
[test1]ouoieuoeiue
dklò[kòl
iuos[test2]
[Another]
qq=10
bb=212341531
cc=45
[LastSection]
jj=123
____________________________________________________________________________
Windows 10 Pro 64 bit - Autohotkey v1.1.30.01 64-bit Unicode
AHKStudent
Posts: 1472
Joined: 05 May 2018, 12:23

Re: Edit text within an .ini file

20 Oct 2019, 12:17

Odlanir wrote:
20 Oct 2019, 11:56
This should work:

Code: Select all

FileDelete, TestINI_New.ini
FileRead, AllFile, TestINI.ini
FileAppend, % RegExReplace(AllFile, "`amsU)(?<=\[Recent\])(.*)(?=^\[\w+]$)","`n`n`n$2"), TestINI_New.ini
run, TestINI_New.ini
Tested with this sample ini:
[Preferences]
color=#ff00ee
size=34
etc.
[Bookmarks]
kk=10
ss=20
jj=30
[Recent]
sei[braketopen
runjowoeud
[]
aaa[inside]dadad
[test1]ouoieuoeiue
dklò[kòl
iuos[test2]
[Another]
qq=10
bb=212341531
cc=45
[LastSection]
jj=123
That is amazing :thumbup: , it motivates me to learn regex, sorry OP for my long code
Lem2001
Posts: 127
Joined: 27 Jun 2017, 17:59

Re: Edit text within an .ini file

21 Oct 2019, 23:36

AHKStudent wrote:
20 Oct 2019, 12:17
sorry OP for my long code
Not at all.

I am grateful to you for taking the time to reply to try to help me.
Lem2001
Posts: 127
Joined: 27 Jun 2017, 17:59

Re: Edit text within an .ini file

21 Oct 2019, 23:37

Odlanir wrote:
20 Oct 2019, 11:56
This should work:
This is amazing!

It covers every possible instance while keeping the next section heading (and the rest of the ini content) safe.

Thank you so much for your help.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: Edit text within an .ini file

22 Oct 2019, 02:24

Odlanir wrote:

Code: Select all

RegExReplace(AllFile, "`amsU)(?<=\[Recent\])(.*)(?=^\[\w+]$)","`n`n`n$2")
It seems that only two blank lines is here. 3 blank lines require 4 line breaks. $2 does nothing, it's redundant.
Odlanir
Posts: 659
Joined: 20 Oct 2016, 08:20

Re: Edit text within an .ini file

22 Oct 2019, 02:56

@teadrinker You're right! Thanks.
____________________________________________________________________________
Windows 10 Pro 64 bit - Autohotkey v1.1.30.01 64-bit Unicode
Lem2001
Posts: 127
Joined: 27 Jun 2017, 17:59

Re: Edit text within an .ini file

22 Oct 2019, 09:08

teadrinker wrote:
22 Oct 2019, 02:24
3 blank lines require 4 line breaks.
Yeah, that was the only part of the Regex command that I understood, so I had already fixed that bit by just adding another line break.


teadrinker wrote:
22 Oct 2019, 02:24
$2 does nothing, it's redundant.
I didn't know what $2 did, so I just left it alone. But now that I know it's not needed, I have gone ahead and removed it.

Thanks.
Lem2001
Posts: 127
Joined: 27 Jun 2017, 17:59

Re: Edit text within an .ini file

22 Oct 2019, 16:12

I can't believe that I am back asking for help on this topic again <sigh>. Sorry.

Everything was working great, but I have discovered that after cleaning, when I next run the software (and more recent entries get created) the [Recent] section has moved to the very end of the .ini file! Presumably it did this because there were no longer any recent entries to keep the [Recent] heading where it was originally located, so the original got wiped and the new [Recent] appended at the end of the ini file instead.

This means that there is not always a subsequent section heading after [Recent], and in that instance the recent entries don't get deleted.

The existing Regex works perfectly when [Recent] is not the last heading in the ini file. Is it possible to incorporate detecting the end of a file too? so that if there is no section heading after [Recent] before the end of the file, that it deletes the contents after Recent to the end of the file (except for leaving 3 blank lines as previously).

Such a command does makes me a little nervous (because I wouldn't want it to accidentally wipe the entire file under certain circumstances) therefore I don't want to attempt messing about with the Regex myself to try to achieve this.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: Edit text within an .ini file

22 Oct 2019, 18:06

Something like this:

Code: Select all

RegExReplace(AllFile, "s)(^|\R)\[Recent](?=(\R|$))\K(.*?(?=\R\[\w+](?2))|(.(?!.*\R\[\w+](?2))+)*$)", "`n`n`n")
Lem2001
Posts: 127
Joined: 27 Jun 2017, 17:59

Re: Edit text within an .ini file

27 Oct 2019, 12:45

teadrinker wrote:
22 Oct 2019, 18:06
Something like this:

Code: Select all

RegExReplace(AllFile, "s)(^|\R)\[Recent](?=(\R|$))\K(.*?(?=\R\[\w+](?2))|(.(?!.*\R\[\w+](?2))+)*$)", "`n`n`n")
Thank you very much. This works great!

I was ready to closely examine the changes made to the Regex command (compared to the previous solution) to see if I could start to get a basic understanding of the piece of the Regex that was added to give the ability to remove 'Recent' entries even when the [Recent] section header was located at the end of the ini file.

However, the changes are so significant compared to the original that I haven't got a clue what the hell is going on :lol:
I'm just grateful that it works.

Thanks again, teadrinker and Odlanir.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: dipahk, Gemos, Nerafius and 196 guests