{"id":20826943,"url":"https://github.com/mklement0/trl","last_synced_at":"2026-01-23T17:33:40.024Z","repository":{"id":33741462,"uuid":"37396153","full_name":"mklement0/trl","owner":"mklement0","description":"Unix CLI for transforming lists of unquoted or quoted strings","archived":false,"fork":false,"pushed_at":"2022-12-27T14:08:08.000Z","size":51,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-23T21:59:38.546Z","etag":null,"topics":["cli","delimiter","multiline","separator","single-line","text-formatting","text-parsing","text-processing","transformations","unix-cli"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mklement0.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-14T02:32:55.000Z","updated_at":"2023-01-18T19:30:00.000Z","dependencies_parsed_at":"2023-01-15T02:17:51.810Z","dependency_job_id":null,"html_url":"https://github.com/mklement0/trl","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/mklement0/trl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Ftrl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Ftrl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Ftrl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Ftrl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mklement0","download_url":"https://codeload.github.com/mklement0/trl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mklement0%2Ftrl/sbom","scorecard":{"id":652620,"data":{"date":"2025-08-11","repo":{"name":"github.com/mklement0/trl","commit":"db9153bd34db8b64d610bfce499c0b7ed4c2d687"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/11 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-21T13:51:34.677Z","repository_id":33741462,"created_at":"2025-08-21T13:51:34.677Z","updated_at":"2025-08-21T13:51:34.677Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28696722,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T17:25:48.045Z","status":"ssl_error","status_checked_at":"2026-01-23T17:25:47.153Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","delimiter","multiline","separator","single-line","text-formatting","text-parsing","text-processing","transformations","unix-cli"],"created_at":"2024-11-17T23:10:37.099Z","updated_at":"2026-01-23T17:33:40.005Z","avatar_url":"https://github.com/mklement0.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm version](https://img.shields.io/npm/v/trl.svg)](https://npmjs.com/package/trl) [![license](https://img.shields.io/npm/l/trl.svg)](https://github.com/mklement0/trl/blob/master/LICENSE.md)\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n**Contents**\n\n- [trl \u0026mdash; introduction](#trl-\u0026mdash-introduction)\n- [Examples](#examples)\n- [Installation](#installation)\n  - [Installation from the npm registry](#installation-from-the-npm-registry)\n  - [Manual installation](#manual-installation)\n- [Usage](#usage)\n- [License](#license)\n  - [Acknowledgements](#acknowledgements)\n  - [npm dependencies](#npm-dependencies)\n- [Changelog](#changelog)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n# trl \u0026mdash; transform lists of strings\n\n`trl` is a Unix CLI that ***tr***ansforms ***l***ists of quoted and/or unquoted strings, by default between single- and multi-line forms.\n\nBoth single- and double-quotes are recognized as input field (item) delimiters, and embedded quotes of the same type must be `\\`-escaped.\n\nSeparators, delimiters, and wrapper strings are configurable, allowing for flexible transformations (reformatting) to and from a wide range of simple formats.\n\n**Note**:\n\n * In the input, for embedded quotes of the same type to be properly  \n   recognized as literals inside quoted tokens, they must be  \n   backslash-escaped.  \n\n * However, with multi-line input, if a given line is not quoted as a whole,  \n   backslash-escaping is implicitly applied to any single- or double-quotes  \n   on the line, allowing lines with imbalanced quotes, such as `Ten o'clock`.  \n   By contrast, if your input lines each contain multiple, individually quoted  \n   tokens, use `-x` to suppress this behavior; otherwise, such lines will be  \n   treated as a single token each, with embedded quotes escaped on output.\n\n * CAVEAT: Malformed input can result in LOSS OF TOKENS on output.\n\n * Similarly, on output, embedded instances of the output delimiters are  \n   `\\`-escaped.  \n\nInput is provided via one or more arguments, or via stdin.\n\nSee the examples below, concise [usage information](#usage) further below,\nor read the [manual](doc/trl.md).\n\n# Examples\n\n```shell\n  # Single-line list to multi-line list:\n$ trl '\"one\", \"two\", \"three \\\" of rain\"'\none\ntwo\nthree \" of rain\n\n  # List to C-style array:\n$ trl -S ', ' -D \\\" -W '{  }' one two three 'four (4)'\n{ \"one\", \"two\", \"three\", \"four (4)\" }\n\n  # Multi-line to single-line:\n$ trl \u003c\u003cEOF\none\ntwo\nthree \" of rain\nEOF\n\"one\", \"two\", \"three \\\" of rain\"\n\n  # Multi-line list with multiple items each to Python array;\n  # note the use of -x to ensure that the indvidually quoted\n  # tokens are properly recognized. \n$ trl -x -s ' ' -S ', ' -D \\' -W '[]' \u003c\u003cEOF\none \"two (2)\"\nthree 'four'\nEOF\n['one', 'two (2)', 'three', 'four']\n\n  # US-format telephone number to CSV:\n$ trl -s '[() -]' -S , '(789) 123-456'\n789,123,456\n```\n\n# Installation\n\n**Supported platforms**\n\n* When installing from the **npm registry**: **Linux** and **OSX**, with [**Perl**](http://www.perl.org/) installed (Perl comes with OSX, as do most Linux distros).\n* When installing **manually**: any **Unix-like** platform with **Bash** and **Perl**.\n\n## Installation from the npm registry\n\n\u003csup\u003eNote: Even if you don't use Node.js, its package manager, `npm`, works across platforms and is easy to install; try [`curl -L http://git.io/n-install | bash`](https://github.com/mklement0/n-install)\u003c/sup\u003e\n\nWith [Node.js](http://nodejs.org/) or [io.js](https://iojs.org/) installed, install [the package](https://www.npmjs.com/package/trl) as follows:\n\n    [sudo] npm install trl -g\n\n**Note**:\n\n* Whether you need `sudo` depends on how you installed Node.js / io.js and whether you've [changed permissions later](https://docs.npmjs.com/getting-started/fixing-npm-permissions); if you get an `EACCES` error, try again with `sudo`.\n* The `-g` ensures [_global_ installation](https://docs.npmjs.com/getting-started/installing-npm-packages-globally) and is needed to put `trl` in your system's `$PATH`.\n\n## Manual installation\n\n* Download [the CLI](https://raw.githubusercontent.com/mklement0/trl/stable/bin/trl) as `trl`.\n* Make it executable with `chmod +x trl`.\n* Move it or symlink it to a folder in your `$PATH`, such as `/usr/local/bin` (OSX) or `/usr/bin` (Linux).\n\n# Usage\n\nFind concise usage information below; for complete documentation, read the\n[manual online](doc/trl.md), or, once installed, run `man trl`\n(`trl --man` if installed manually).\n\n\u003c!-- DO NOT EDIT THE FENCED CODE BLOCK and RETAIN THIS COMMENT: The fenced code block below is updated by `make update-readme/release` with CLI usage information. --\u003e\n\n```nohighlight\n$ trl --help\n\n\nTransforms lists of unquoted and/or quoted strings.\n\n    trl [\u003coptions\u003e] [\u003ctext\u003e...]\n\n    -s \u003cinSep\u003e      input list separator\n    -S \u003coutSep\u003e     output list separator\n    -k              keep input item delimiters\n    -D \u003coutDelim\u003e   output item delimiter (cannot be combined with -k)\n    -W \u003cwrapText\u003e   text to wrap the result list in\n    -R \u003cors\u003e        output record separator (multi-line + multi-item-per-line\n                    input only)\n    -x              do not auto-escape quotes on lines not quoted as a whole\n\nBy default,\n\n * a multi-line list is transformed to a single-line list with double-quoted  \n   items separated by a comma followed by a space.\n * a single-line list is transformed to a multi-line list with unquoted items.\n\nStandard options: --help, --man, --version, --home\n```\n\n\u003c!-- DO NOT EDIT THE NEXT CHAPTER and RETAIN THIS COMMENT: The next chapter is updated by `make update-readme/release` with the contents of 'LICENSE.md'. ALSO, LEAVE AT LEAST 1 BLANK LINE AFTER THIS COMMENT. --\u003e\n\n# License\n\nCopyright (c) 2015-2016 Michael Klement \u003cmklement0@gmail.com\u003e (http://same2u.net), released under the [MIT license](https://spdx.org/licenses/MIT#licenseText).\n\n## Acknowledgements\n\nThis project gratefully depends on the following open-source components, according to the terms of their respective licenses.\n\n[npm](https://www.npmjs.com/) dependencies below have optional suffixes denoting the type of dependency; the *absence* of a suffix denotes a required *run-time* dependency: `(D)` denotes a *development-time-only* dependency, `(O)` an *optional* dependency, and `(P)` a *peer* dependency.\n\n\u003c!-- DO NOT EDIT THE NEXT CHAPTER and RETAIN THIS COMMENT: The next chapter is updated by `make update-readme/release` with the dependencies from 'package.json'. ALSO, LEAVE AT LEAST 1 BLANK LINE AFTER THIS COMMENT. --\u003e\n\n## npm dependencies\n\n* [doctoc (D)](https://github.com/thlorenz/doctoc)\n* [json (D)](https://github.com/trentm/json)\n* [marked-man (D)](https://github.com/kapouer/marked-man#readme)\n* [replace (D)](https://github.com/harthur/replace)\n* [semver (D)](https://github.com/npm/node-semver#readme)\n* [tap (D)](https://github.com/isaacs/node-tap)\n* [urchin (D)](https://git.sdf.org/tlevine/urchin)\n\n\u003c!-- DO NOT EDIT THE NEXT CHAPTER and RETAIN THIS COMMENT: The next chapter is updated by `make update-readme/release` with the contents of 'CHANGELOG.md'. ALSO, LEAVE AT LEAST 1 BLANK LINE AFTER THIS COMMENT. --\u003e\n\n# Changelog\n\nVersioning complies with [semantic versioning (semver)](http://semver.org/).\n\n\u003c!-- NOTE: An entry template for a new version is automatically added each time `make version` is called. Fill in changes afterwards. --\u003e\n\n* **[v0.4.0](https://github.com/mklement0/trl/compare/v0.3.3...v0.4.0)** (2016-06-04):\n  * [breaking change, enhancement] embedded instances of output separators are\n    now get `\\`-escaped on output.\n  * [breaking change, enhancement] for multi-line input, any line that isn't \n    quoted as a whole is now by default interpreted as a single token whose\n    embedded quotes, if any, are treated as literals; use `-x` to suppress this\n    behavior (assumes that your lines contain multiple, indvidually quoted\n    tokens whose embedded quotes of the same type, if any, are `\\`-escaped).\n\n* **[v0.3.3](https://github.com/mklement0/trl/compare/v0.3.2...v0.3.3)** (2015-09-19):\n  * [doc] `trl` now has a man page (if manually installed, use `trl --man`);\n          `trl -h` now just prints concise usage information.\n\n* **[v0.3.2](https://github.com/mklement0/trl/compare/v0.3.1...v0.3.2)** (2015-09-15):\n  * [dev] Makefile improvements; various other behind-the-scenes tweaks.\n\n* **[v0.3.1](https://github.com/mklement0/trl/compare/v0.3.0...v0.3.1)** (2015-06-24):\n  * [doc] Copy-editing of CLI help and read-me.\n\n* **[v0.3.0](https://github.com/mklement0/trl/compare/v0.2.0...v0.3.0)** (2015-06-24):\n  * [new feature, behavior change] The output-delimiter string passed to `-D` may now be a symmetrical *multi-character* string such as `()`, in which case the 1st _half_ acts as the opening delimiter, and the 2nd half as the closing delimiter.\n  * [new feature, behavior change] The wrapper string passed to `-W` may now be a *single* character (in addition to a symmetrical multi-char. string), in which case that same character is used as both the opening and closing wrapper text.\n\n* **[v0.2.0](https://github.com/mklement0/trl/compare/v0.1.1...v0.2.0)** (2015-06-23):\n  * [fix resulting in behavior change] Specifying a multi-line list as the only operand (e.g., `trl \u003c\u003c\u003c$'line 1\\nline 2\\nline 3'` now behaves the same as passing the same string via stdin; i.e., in both cases, the result is a *single-line* list.\n\n* **[v0.1.1](https://github.com/mklement0/trl/compare/v0.1.0...v0.1.1)** (2015-06-14):\n  * [doc] Fixed formatting of examples.\n\n* **v0.1.0** (2015-06-14):\n  * Initial release.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmklement0%2Ftrl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmklement0%2Ftrl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmklement0%2Ftrl/lists"}