{"id":16483506,"url":"https://github.com/dbohdan/initool","last_synced_at":"2026-01-27T23:49:10.808Z","repository":{"id":33439276,"uuid":"37084600","full_name":"dbohdan/initool","owner":"dbohdan","description":"Manipulate INI files from the command line","archived":false,"fork":false,"pushed_at":"2024-11-18T09:58:11.000Z","size":172,"stargazers_count":64,"open_issues_count":3,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-01-11T12:17:42.850Z","etag":null,"topics":["cli","configuration-file","ini","standard-ml"],"latest_commit_sha":null,"homepage":"","language":"Standard ML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dbohdan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-06-08T18:22:06.000Z","updated_at":"2024-12-18T09:45:53.000Z","dependencies_parsed_at":"2022-09-07T05:40:07.399Z","dependency_job_id":"ea18ef4c-1f49-4f8d-9df9-597896327a5c","html_url":"https://github.com/dbohdan/initool","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbohdan%2Finitool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbohdan%2Finitool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbohdan%2Finitool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbohdan%2Finitool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dbohdan","download_url":"https://codeload.github.com/dbohdan/initool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241215473,"owners_count":19928486,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","configuration-file","ini","standard-ml"],"created_at":"2024-10-11T13:14:14.995Z","updated_at":"2026-01-27T23:49:00.795Z","avatar_url":"https://github.com/dbohdan.png","language":"Standard ML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# initool\n\nInitool lets you manipulate the contents of INI files from the command line.\nRather than modify an INI file in place, it prints the modified contents of the file to standard output.\n\n\n## Contents\n\n- [Operation](#operation)\n  - [Usage](#usage)\n  - [Examples](#examples)\n    - [POSIX](#posix)\n    - [Windows](#windows)\n    - [Both](#both)\n      - [PowerShell](#powershell)\n      - [Most shells](#most-shells)\n  - [Whitespace](#whitespace)\n  - [Nonexistent sections and properties](#nonexistent-sections-and-properties)\n  - [Unparsable lines](#unparsable-lines)\n  - [Line endings](#line-endings)\n  - [Case sensitivity](#case-sensitivity)\n  - [Repeated items](#repeated-items)\n  - [Text encodings](#text-encodings)\n- [Building and installation](#building-and-installation)\n  - [Prebuilt binaries](#prebuilt-binaries)\n  - [FreeBSD, MacPorts port](#freebsd-macports-port)\n  - [Windows package](#windows-package)\n  - [Building on FreeBSD, Linux, macOS](#building-on-freebsd-linux-macos)\n  - [Building for Linux with Docker](#building-for-linux-with-docker)\n  - [Building on Windows](#building-on-windows)\n- [License](#license)\n\n\n## Operation\n\n### Usage\n\n```none\ninitool [-i|--ignore-case] [-p|--pass-through] \u003ccommand\u003e [\u003carg\u003e ...]\n```\n\nThe following commands are available:\n\n- `get \u003cfilename\u003e [\u003csection\u003e [\u003ckey\u003e [-v|--value-only]]]` — retrieve data.\n- `exists \u003cfilename\u003e \u003csection\u003e [\u003ckey\u003e]` — check if a section or a property exists.\n- `set \u003cfilename\u003e \u003csection\u003e \u003ckey\u003e \u003cvalue\u003e` — set a property's value.\n- `replace \u003cfilename\u003e \u003csection\u003e \u003ckey\u003e \u003ctext\u003e \u003creplacement\u003e` — replace the first occurrence of `\u003ctext\u003e` with `\u003creplacement\u003e` in the property's value. Empty `\u003ctext\u003e` matches empty values.\n- `delete \u003cfilename\u003e \u003csection\u003e [\u003ckey\u003e]` — delete a section or a property.\n- `help` — print the help message.\n- `version` — print the version number.\n\nCommands can be abbreviated to their first letter: `g`, `e`, `s`, `r`, `d`, `h`, `v`.\nThe global options `-i`/`--ignore-case` and `-p`/`--pass-through` must precede the command name.\n\nWhen given a valid command, initool first reads the INI file `filename` in its entirety.\nIf the filename is `-`, initool reads standard input. For the commands `get`, `set`, `replace`, and `delete`, it then prints to standard output the file's contents with the desired change.\nFor `exists`, it reports whether the section or the property exists through its exit status.\n\n**Initool never modifies the input file.**\nOne exception is if you redirect initool's output to the same file as input, which results in an empty file\n[like with other programs](https://superuser.com/questions/597244/why-does-redirecting-the-output-of-a-file-to-itself-produce-a-blank-file).\nTwo wrapper scripts are included if you want to modify the input file:\n[`initool-overwrite.sh`](initool-overwrite.sh) (POSIX shell)\nand [`initool-overwrite.cmd`](initool-overwrite.cmd) (Windows batch).\nThe scripts redirect the output of initool to a temporary file, then overwrite the original.\n\nAn INI file consists of properties (`key=value` lines) and sections (designated with a `[section name]` header line).\nA property can be at the \"top level\" of the file (before any section headers) or in a section (after a section header).\nTo do something with a property, you must give initool the correct section name.\nSection names and keys are [case-sensitive](#case-sensitivity) by default, as is text for the command `replace`.\nThe global option `-i` or `--ignore-case` makes commands not distinguish between lower-case and upper-case [ASCII](https://en.wikipedia.org/wiki/ASCII) letters \"A\" through \"Z\" in section names, keys, and text.\n\nDo not include the square brackets in the section argument.\n\n```sh\n# Right.\ninitool get tests/test.ini foo\n\n# Wrong.\ninitool get tests/test.ini [foo]\n```\n\nTop-level properties (properties not in any section) are accessed by using an empty string as the section name.\nThe `exists` command with just an empty string as the argument tells you whether or not there are any top-level properties.\n\nThe section name and key can be `*` or `_` (a \"wildcard\") to match anything.\nOnly `_` works on Windows.\n(Windows executables built with MoSML unavoidably expand `*` to a list of files.)\nFor example, `set file.ini _ foo bar` will set the key `foo` to the value `bar` in every existing section.\nIt will set the key `foo` at the top level if the file already has top-level properties.\nTo match a one-character section name or key that is `*` or `_`, use `\\*` and `\\_` respectively.\nAn initial backslash is removed from the section name and the key argument.\n\nThe order in which properties appear in the INI file is preserved.\nA new property is added after the last property in its section.\n\nInitool preserves INI file comments in the output when it prints a whole file or a section.\nThe comments are lines where the first character that is not [whitespace](#whitespace) is either `;` or `#`.\nInitool also preserves empty lines.\nDeleting a section removes it comments and empty lines.\n\n### Examples\n\n#### POSIX\n\nLet's replace the value of the top-level property `cache` in the file `settings.ini` from a\n[POSIX-compatible shell](https://en.wikipedia.org/wiki/Unix_shell).\nYou can do this on FreeBSD, Linux, and macOS.\n\n```sh\ninitool set settings.ini '' cache 1024 \u003e settings.ini.new \\\n\u0026\u0026 mv settings.ini.new settings.ini\n```\n\nYou can pipeline invocations of initool to make multiple changes.\nEnable `pipefail` in your shell\n([compatibility information](https://unix.stackexchange.com/a/654932))\nto handle errors correctly.\n\n```sh\nset -o pipefail\ninitool delete settings.ini test \\\n| initool set - '' cache 1024 \u003e settings.ini.new \\\n\u0026\u0026 mv settings.ini.new settings.ini\n```\n\n#### Windows\n\nNow let's replace the value of the top-level property `cache` in the file `settings.ini` on Windows from the Command Prompt (`cmd.exe`):\n\n```batch\ninitool set settings.ini \"\" cache 1024 \u003e settings.ini.new\nif %errorlevel% equ 0 move /y settings.ini.new settings.ini\n```\n\nYou can use pipelines in the Windows Command Prompt,\nalthough there is a reason to avoid them.\nThe Command Prompt has no feature like `pipefail`.\nThe `%errorlevel%` will be that of the last command in the pipeline, which in the example below cannot fail.\nThere is no `%errorlevel%` check in the example because it would be pointless.\n\n```batch\ninitool delete settings.ini test | initool set - \"\" cache 1024 \u003e settings.ini.new\nmove /y settings.ini.new settings.ini\n```\n\n#### Both\n\n##### PowerShell\n\nPowerShell lets you combine initool commands into pipelines\nwithout the same problem as in `cmd.exe` (see above).\nThe variable `$?` will be `True` only if all commands in the pipeline succeed.\n\n```powershell\n# We assume `initool` is installed in `PATH`.\n# Use `./initool` instead if the binary is in the current directory.\ninitool delete settings.ini test | initool set - '' cache 1024 \u003e settings.ini.new\nif ($?) { move -Force settings.ini.new settings.ini }\n```\n\n##### Most shells\n\nThese examples work in POSIX-compatible shells, fish, `cmd.exe`, PowerShell, and others.\n`\u003e` at the beginning of the line represents the shell's prompt.\n\n###### Retrieving a value\n\nTo retrieve only the value of a property rather than the whole property (the section, key, and value), use the flag `-v` or `--value-only`:\n\n```sh\n\u003e initool get tests/test.ini foo name1\n[foo]\nname1=foo1\n\u003e initool get tests/test.ini foo name1 --value-only\nfoo1\n```\n\n###### Replacing text in a value\n\nThe command `replace` can do two related things:\n\n1. Replace the first occurrence of matching text in a property's value.\n   The text can be any continuous part of the value, including the whole value.\n2. Set a property's value only when it is empty.\n\nLet's start with replacing part of a value.\n\n```sh\n\u003e initool get tests/replace-part.ini\nkey=A longer value.\nanother-key=ABAABBAAABBB\nempty=\n\u003e initool replace tests/replace-part.ini \"\" key value string \u003e updated.ini\n```\n\nThe contents of `updated.ini` will be:\n\n```ini\nkey=A longer string.\nanother-key=ABAABBAAABBB\nempty=\n```\n\nNow let's set the value of the key `empty`,\nbut only if it is actually empty.\nUse an empty string as the `\u003ctext\u003e` argument.\n\n```sh\n\u003e initool replace tests/replace-part.ini \"\" empty \"\" no \u003e updated.ini\n```\n\nThe contents of `updated.ini` will be:\n\n```ini\nkey=A longer value.\nanother-key=ABAABBAAABBB\nempty=no\n```\n\n### Whitespace\n\nInitool defines whitespace as any mix of space and tab characters.\nLeading and trailing whitespace around the section name, the key, and the value is removed from the output.\n\nAs a result, the following input files are all equivalent to each other for initool and produce the same output.\nThe output is identical to the first input.\n\n```ini\n[PHP]\nshort_open_tag=Off\n```\n\n```ini\n[PHP]\nshort_open_tag = Off\n```\n\n```ini\n    [PHP]\n        short_open_tag   =     Off\n```\n\nBecause of this, you can reformat initool-compatible INI files with the command `initool get file.ini`.\n\n### Nonexistent sections and properties\n\nHow nonexistent sections and properties are handled depends on the command.\n\n- `get`\n  - **Result:** Initool produces no output when the section or the key doesn't exist.\n  - **Exit status:** 0 if the file, section, or property exists, 1 if it doesn't.\n- `exists`\n  - **Result:** No output.\n  - **Exit status:** 0 if the section or property exists, 1 if it doesn't.\n- `set`\n  - **Result:** The section and the property are created as needed.\n  - **Exit status:** 0.\n- `replace`\n  - **Result:** Nothing from the input changes in the output.\n  - **Exit status:** 0 if the property exists and its value contains the text, 1 if it doesn't exist or the value doesn't contain the text.\n- `delete`\n  - **Result:** Nothing is removed from the input in the output.\n  - **Exit status:** 0 if the section or property was deleted, 1 if it wasn't.\n\n### Unparsable lines\n\nWhen initool encounters a line it cannot parse,\nit normally exits with an error.\nThis prevents problems caused by working on a malformed or non-INI file:\ngetting bogus data out of the file and corrupting the file by applying changes.\nThe global option `-p` or `--pass-through` disables the error and instead makes initool read and write lines verbatim when it fails to parse them.\nLike comments, verbatim lines are treated as parts of their respective sections.\n\nUse pass-through mode at your own risk.\nYou will not be alerted about syntax errors.\nIt may lead to surprising results.\nFor example, if a section header contains a typo like `[foo[`,\nthe properties in that section will be treated as belonging to the previous section.\n\n### Line endings\n\nWhen compiled according to the instructions below, initool will assume line endings to be LF on POSIX and either LF or CR+LF on Windows.\nTo operate on Windows files from POSIX, convert the files' line endings to LF and then back.\nYou can do this [with sed(1)](http://stackoverflow.com/a/2613834).\n\n### Case sensitivity\n\nInitool is [case-sensitive](https://en.wikipedia.org/wiki/Case_sensitivity) by default.\nThis means that it considers `[BOOT]` and `[boot]` different sections and `foo=5` and `FOO=5` properties with different keys.\nThe option `-i`/`--ignore-case` changes this behavior.\nIt makes initool treat ASCII letters \"A\" through \"Z\" and \"a\" through \"z\" as equal\nwhen looking for sections and keys (every command) and text in values (`replace`).\nThe case of section names and keys is preserved in the output regardless of the `-i`/`--ignore-case` option.\n\n### Repeated items\n\nIf a file has multiple sections with identical names or identical keys in the same section, initool preserves them.\nCommands act on all of them at the same time.\n\n### Text encodings\n\nInitool is encoding-naive and assumes one character is one byte.\nIt correctly processes UTF-8-encoded files when given UTF-8 command-line arguments.\nIt exits with an encoding error if it detects the UTF-16 or UTF-32 [BOM](https://en.wikipedia.org/wiki/Byte_order_mark).\nTrying to open a UTF-16 or UTF-32 file without the BOM results in an \"invalid line\" error because initool is unable to parse it.\n\nOn Windows, initool will receive the command-line arguments in the encoding for your system's language for non-Unicode programs (e.g., [Windows-1252](https://en.wikipedia.org/wiki/Windows-1252)),\nwhich limits what you can do with UTF-8-encoded files.\n\n\n## Building and installation\n\n### Prebuilt binaries\n\nPrebuilt binaries for Linux (x86-64), macOS (ARM64 and x86-64), and Windows (x86)\nare attached to\n[releases](https://github.com/dbohdan/initool/releases).\nCI also builds a set of test binaries for every Git push.\n\nLinux and macOS binary distributions include a copy of the\n[GNU Multiple Precision Arithmetic Library](https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library)\nused under the GNU LGPL version 3.\n\nBSD, Linux, and macOS binaries are not marked as executable because of a\n[limitation of `@actions/upload-artifact`](https://github.com/actions/upload-artifact/issues/38).\nExtract the archive and run the command\n\n```sh\nchmod +x initool\n```\n\nOn macOS, you may need to run the following command once you have extracted the archive:\n\n```sh\nxattr -d com.apple.quarantine initool\n```\n\n### FreeBSD, MacPorts port\n\nYou can install `sysutils/initool` from the FreeBSD ports tree and MacPorts.\n\n### Windows package\n\nInitool can be installed with Chocolatey:\n\n```batch\nchoco install initool\n```\n\n### Building on FreeBSD, Linux, macOS\n\nInstall [MLton](http://mlton.org/).\nIt is available as the package `mlton` in Fedora, FreeBSD, Homebrew, MacPorts, Ubuntu 24.04, and\n[other repositories](https://repology.org/project/mlton/versions).\nOn Debian 12 and Ubuntu 22.04, you will have to build MLton from source.\n\nClone the repository and run `make` then `sudo make install` in it.\nInitool will be installed in `/usr/local/bin`.\nRun `sudo make uninstall` to remove it.\n\n### Building for Linux with Docker\n\nYou can build and run initool using Docker.\n\nTo build a Docker image for initool,\nclone the repository,\n`cd` to its directory,\nthen run the build command:\n\n```sh\ndocker build -t initool:latest .\n```\n\nWait for the build to finish.\nOnce it succeeds,\nyou can run initool from the Docker image you have built.\n\nThe following Docker command runs initool and gives it access to the current directory:\n\n```sh\ndocker run --rm --user \"$(id -u):$(id -g)\" --volume \"$PWD:/mnt/\" --workdir /mnt/ initool:latest help\n```\n\nPass in arguments to initool after `initool:latest`.\nYou may notice a delay when starting initool in a Docker container.\n\nIf you plan to use initool repeatedly,\nyou have the option to copy the binary to your Linux system.\nThis command copies the binary to the current directory:\n\n```sh\ndocker run --entrypoint /bin/sh --rm --user \"$(id -u):$(id -g)\" --volume \"$PWD:/mnt/\" --workdir /mnt/ initool:latest -c 'cp /app/initool/initool /mnt/'\n```\n\n### Building on Windows\n\nTo build initool yourself, first install [MoSML](http://mosml.org).\nThe Windows installer is not available on the official site due to an antivirus false positive.\nI have [mirrored the installer](https://github.com/kfl/mosml/issues/49#issuecomment-368878055) in an attachment to a GitHub comment.\n\nClone the repository and run `build.cmd` from its directory.\n\nTo test on Windows, download [busybox-w32](https://frippery.org/busybox/) as `busybox.exe` to the repository directory, then run `test.cmd`.\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbohdan%2Finitool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdbohdan%2Finitool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbohdan%2Finitool/lists"}