Updated! What's new: Features: [*]The script relies on a file named "sectionlist.txt" which has to be in the same folder and is in fact a .ini file. This file is used to determine which section of the install.ini should be treated and appear in the output file. The script is not able (yet) to find all section itself. [*]Shortest example: a "[main]" section, a "list" key and all sections, separated with ";". #NoTrayIcon IfNotExist, %A_ScriptDir%\SectionList.txt { IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, list IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, SectionSort IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, clean_level IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, Sort IniWrite, %blank_var%, %A_ScriptDir%\sectionlist.txt, main, special_dark MsgBox, 0, Fatal Error, SectionList.txt could not be found`, check this file is present and try again! ExitApp } IniRead, sectionlist, %A_ScriptDir%\sectionlist.txt, main, list, 0 if !sectionlist { MsgBox, 0 Fatal Error, Sectionlist.txt does not contain the names of the sections to sort! ExitApp } IniRead, SortSections, %A_ScriptDir%\sectionlist.txt, main, SectionSort, 1 if (SortSections) Sort, sectionlist, D`; IniRead, input, %A_ScriptDir%\sectionlist.txt, main, input, %A_Space% IniRead, output, %A_ScriptDir%\sectionlist.txt, main, output, %A_Space% Gui, Add, Text, y9, Input file : Gui, Add, Edit, vsource x15 w300, %input% Gui, Add, Button, gBrowseInput x320 y27 w60, Browse Gui, Add, Text, x10, Output File : Gui, Add, Edit, vout x15 w300, %output% Gui, Add, Button, gBrowseOutput x320 y74 w60, Browse Gui, Add, Text, x10, Maximal Index : Gui, Add, DDL, vmax w60 x15, 10|20|40|60|80||100|120|150|180|200 Gui, Add, Button, gRun x170 y144 w50, Run! ShowMain: Gui, Show return BrowseInput: Gui, +OwnDialogs FileSelectFile, source, 1, %input%, Please select the file to be sorted. GuiControl,, source, %source% Gui, Submit if (!out AND !output) { StringGetPos, pos, source, `\, R StringTrimRight, out, source, Strlen(source)-pos GuiControl,, out, %out%\install_sorted.ini } Gui, Show return BrowseOutput: Gui, +OwnDialogs if (out) FileSelectFile, out, S2, %out%\install_sorted.ini, Please select where to place the file once sorted. else FileSelectFile, out, S2, %output%, Please select where to place the file once sorted. if (out) GuiControl,, out, %out% Gui, Show return Run: Gui, Submit Gui, +OwnDialogs IfNotExist, %source% { MsgBox, 0, Error!, Input file could not be found Goto, ShowMain } if (source=out) { MsgBox, 0, Error, Input and output files must be different!`r`nPlease change this. Goto, ShowMain } MsgBox, 0, Processing..., The script will take some time to complete.`r`nPlease press OK and wait. IniWrite, %source%, %A_ScriptDir%\sectionlist.txt, main, input IniWrite, %out%, %A_ScriptDir%\sectionlist.txt, main, output FileDelete, %out% Loop, Parse, sectionlist, `;;parses sections to sort { section:=A_LoopField IniRead, clean_level, %A_ScriptDir%\sectionlist.txt, %section%, clean_level, ù if (clean_level="ù") { IniRead, clean_level, %A_ScriptDir%\sectionlist.txt, main, clean_level, ù if (clean_level="ù") { IniWrite, 0, %A_ScriptDir%\sectionlist.txt, main, clean_level IniWrite, 0, %A_ScriptDir%\sectionlist.txt, %section%, clean_level clean_level=0 } else IniWrite, %clean_level%, %A_ScriptDir%\sectionlist.txt, %section%, clean_level } IniRead, Sort, %A_ScriptDir%\sectionlist.txt, %section%, Sort, ù if (Sort="ù") { IniRead, Sort, %A_ScriptDir%\sectionlist.txt, main, Sort, ù if (Sort="ù") { IniWrite, 0, %A_ScriptDir%\sectionlist.txt, main, Sort IniWrite, 0, %A_ScriptDir%\sectionlist.txt, %section%, Sort Sort=0 } else IniWrite, %Sort%, %A_ScriptDir%\sectionlist.txt, %section%, Sort } IniRead, special_dark, %A_ScriptDir%\sectionlist.txt, %section%, special_dark, ù if (special_dark="ù") { IniRead, special_dark, %A_ScriptDir%\sectionlist.txt, main, special_dark, ù if (special_dark="ù") { IniWrite, 0, %A_ScriptDir%\sectionlist.txt, main, special_dark IniWrite, 0, %A_ScriptDir%\sectionlist.txt, %section%, special_dark special_dark=0 } else IniWrite, %special_dark%, %A_ScriptDir%\sectionlist.txt, %section%, special_dark } Write("","", "description");calls the write function for each item (exceptionnal one) Write("", "", "command") Write("", "", "selected") Write("", "", "hidden") Write("", "", "collapsed") Write("", "", "locked") Write("", "", "disabled") Write("", "", "group") Write("", "", "flags") Write("", "", "workdir") Write("", "", "helptext") Write("", "", "ext_creator_switchtype") Write("", "", "ext_creator_originalcommand") Sort() } Sort(oldlevel="", newlevel="") {;the main function, recursively called Global max, source, out, section, Sort, special_dark Loop, %max% { i:=A_Index - 1;WIHU's first index is 0 whereas AHK's one is 1 IniRead, iuv, %source%, %section%, description%oldlevel%.%i%, %A_Space%;retrieves sections description if (iuv="");avoid adding non-existant indexes continue if (Names);appends a semi-column and the section name (iuv) with its old index (@i) to the list, except if ... Names:=Names ";" iuv "@" i else;... except if the list is still empty (would bug otherwise) Names:=iuv "@" i } if (Sort) Sort, Names, D`; StringSplit, Names, Names, `; Loop, %Names0% { i:=A_Index - 1;same as before : WIHU's first index is 0 whereas AHK's one is 1 Stringsplit, oldrank, Names%A_Index%, `@;retrieves old index Write(oldlevel "." oldrank2, newlevel "." i, "description");calls the write function for each item Write(oldlevel "." oldrank2, newlevel "." i, "command") Write(oldlevel "." oldrank2, newlevel "." i, "selected") Write(oldlevel "." oldrank2, newlevel "." i, "hidden") Write(oldlevel "." oldrank2, newlevel "." i, "collapsed") Write(oldlevel "." oldrank2, newlevel "." i, "locked") Write(oldlevel "." oldrank2, newlevel "." i, "disabled") Write(oldlevel "." oldrank2, newlevel "." i, "group") Write(oldlevel "." oldrank2, newlevel "." i, "flags") Write(oldlevel "." oldrank2, newlevel "." i, "workdir") Write(oldlevel "." oldrank2, newlevel "." i, "helptext") Write(oldlevel "." oldrank2, newlevel "." i, "ext_creator_switchtype") Write(oldlevel "." oldrank2, newlevel "." i, "ext_creator_originalcommand") IniRead, iuv, %source%, %section%, description%oldlevel%.%oldrank2%.0, %A_Space%;is there a deeper level to sort ? if (iuv!="") Sort(oldlevel "." oldrank2, newlevel "." i);recursive call because when there is a deeper level } } FileRead, sorted, %out%;needed for the three followig lines StringReplace, sorted, sorted, description, `r`ndescription, All;adds linefeeds so the file can be read by an human StringReplace, sorted, sorted, [, `r`n[, All;same StringReplace, sorted, sorted, ]`r`n, ], All;removes some non-necessary linefeeds introduced just before StringReplace, sorted, sorted, `r`n[, [; removes the first linefeed FileDelete, %out%;deletes the file so... FileAppend, %sorted%, %out%;it can be 'overwritten' MsgBox, 0, Operation Complete, Input file has been sorted. GuiClose: ExitApp Write(old, new, var) {;the function used to write in the ini global source, out, section, clean_level IniRead, iuv, %source%, %section%, %var%%old%, ù;retrieves the value at the old position ;if (clean_level="-1") {;if you want to bloat your file, not available ATM ; if (iuv="ù") ; iuv=0 ; IniWrite, %blank_var%, %out%, %section%, %var%%new% if (clean_level="0" AND iuv!="ù");keys with empty values are not copied over, should *maybe* be changed IniWrite, %iuv%, %out%, %section%, %var%%new%;writes the new value if (clean_level="1" AND iuv!="ù" AND iuv);keys with empty values are not copied over, should *maybe* be changed IniWrite, %iuv%, %out%, %section%, %var%%new%;writes the new value }