{"id":25837248,"url":"https://github.com/devtin/csv-tr","last_synced_at":"2025-08-24T09:49:53.319Z","repository":{"id":57211000,"uuid":"434987210","full_name":"devtin/csv-tr","owner":"devtin","description":"cli utility to transform and sort csv files","archived":false,"fork":false,"pushed_at":"2024-03-21T15:20:34.000Z","size":264,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-08T00:38:24.350Z","etag":null,"topics":["cli","csv","filter","sort","transform"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/devtin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2021-12-04T19:09:16.000Z","updated_at":"2023-03-20T15:43:38.000Z","dependencies_parsed_at":"2024-03-21T16:51:57.757Z","dependency_job_id":null,"html_url":"https://github.com/devtin/csv-tr","commit_stats":{"total_commits":24,"total_committers":2,"mean_commits":12.0,"dds":"0.20833333333333337","last_synced_commit":"583bec284f8c2f302c271e00f875bfdfc9b8d6c3"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devtin%2Fcsv-tr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devtin%2Fcsv-tr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devtin%2Fcsv-tr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devtin%2Fcsv-tr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devtin","download_url":"https://codeload.github.com/devtin/csv-tr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241309091,"owners_count":19941726,"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","csv","filter","sort","transform"],"created_at":"2025-03-01T02:48:03.444Z","updated_at":"2025-03-01T02:48:03.920Z","avatar_url":"https://github.com/devtin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# csv-tr\n\n\u003cp\u003e\n    \u003ca href=\"https://www.npmjs.com/package/csv-tr\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/csv-tr.svg\" alt=\"Version\"\u003e\u003c/a\u003e\n\u003ca href=\"http://opensource.org/licenses\" target=\"_blank\"\u003e\u003cimg src=\"http://img.shields.io/badge/License-MIT-brightgreen.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\nUtility to manipulate long csv files\n\n## Manifesto\n\nManipulating long csv files using graphic user interfaces might not be the most efficient at times. I want an utility that\nhelps me manipulate long csv files. This utility should:\n\n- [Filter rows](#filtering-rows)\n- [Transform rows](#transforming-rows)\n- [Select specific columns](#selecting-specific-columns)\n- [Exclude specific columns](#excluding-specific-columns)\n- [Sort by columns](#sorting-by-column)\n\n**Glossary of terms**\n\n- **Column**: header column name of a csv file\n- **Index**: line number of a csv file\n- **Row**: line of a csv file\n\n## Installation\n\n```shell\nnpm install --global csv-tr\n```\n\nusing `yarn`\n\n```shell\nyarn add global csv-tr\n```\n\nusing `npx`\n\n```shell\nnpx csv-tr --help\n```\n\n## CLI usage\n\n```text\nUsage: csv-tr [options] [source | input stream]\n\ntransforms given csv file or stream and outputs the result\n\nOptions:\n  -V, --version                                             output the version number\n  -o, --only \u003ccolumns\u003e                                      output only specified columns (comma separated). Not to be used with --exclude.\n  -e, --exclude \u003ccolumns\u003e                                   exclude specified columns (comma separated). Not to be used with --only.\n  -t, --transform \u003cjs-file|js-expression\u003e                   transform rows by given JavaScript expression. Ej: -t \"row.email = row.email.toLowerCase()\"\n  -f, --filter \u003cjs-file|js-expression\u003e                      filter rows by given JavaScript file or expression. Ej: -f \"row.state === 'FL'\"\n  -s, --sort \u003c[sort-column]:[sort-order: 1=ASC | -1=DESC]\u003e  sorts rows by column:order (comma separated) Ej: -s \"firstName:1,lastName:-1\"\n  -h, --help                                                display help for command\n```\n\n### Input sample\nImagine a CSV file called `contacts.csv` with content\n\n```csv\nname,email,state\nJuan,juan@gmail.com,FL\nMiguel,miguel@hotmail.com,NY\nJesus,jesus@gmail.com,NY\n```\n\n### Filtering rows\n\nFiltering values using the option `--filter` or `-f` followed by a JavaScript expression that will be evaluated\nagainst a function that must return boolean, and looks like:\n\n```js\n(row, index) =\u003e { return /* your JavaScript expression */ }\n```\n\nAlternatively a file that exports a function with the same signature is also accepted:\n\n```js\n// my-filter-file\nmodule.exports = (row/* , index */) =\u003e {\n  return /@gmail.com$/i.test(row.email)\n}\n```\n\nEach `row` is nothing but a line of the csv file represented as a JSON object streamed by\n\u003ca href=\"https://github.com/mafintosh/csv-parser\" target=\"_blank\"\u003ecsv-parser\u003c/a\u003e.\n\nThe `index` value is given row number starting at `0`. Meaning `index` of the first row (which is not the column names header)\nequals `0`.\n\n```shell\ncsv-tr contacts.csv -f '/@gmail.com$/i.test(row.email)' \u003e gmail-contacts.csv\n```\n\n`gmail-contacts.csv` would look like:\n\n```csv\nname,email,state\nJuan,juan@gmail.com,FL\nJesus,jesus@gmail.com,NY\n```\n\n**Slicing a given range of rows using the `index` value**\n\n```shell\ncsv-tr contacts.csv -f 'index \u003e 0 \u0026\u0026 index \u003c 2'\n```\n\nWould output:\n\n```csv\nname,email,state\nMiguel,miguel@hotmail.com,NY\n```\n\n### Transforming rows\n\nTransforming values using the option `--transform` or `-t` followed by a JavaScript expression that will be evaluated\nagainst a function that looks like.\n\n```js\n(row, index) =\u003e {\n  /* your js mutations go here */\n}\n```\n\nAlternatively a file that exports a function with the same signature is also accepted:\n\n```js\n// my-transform-file\nmodule.exports = (row/* , index */) =\u003e {\n  row.name = row.name.toUpperCase()\n  row.email = row.email.toUpperCase()\n  row.initial = row.name[0]\n\n  return row\n}\n```\n\nUsing the same `contacts.csv` [input sample](#input-sample).\n\n```shell\ncsv-tr contacts.csv -t 'row.name = row.name.toUpperCase(); row.email = row.email.toUpperCase(); row.initial = row.name[0]' \u003e contacts-uppercase.csv\n```\n\n`contacts-uppercase.csv` would look like:\n\n```csv\nname,email,state,initial\nJUAN,JUAN@GMAIL.COM,FL,J\nMIGUEL,MIGUEL@HOTMAIL.COM,NY,M\nJESUS,JESUS@GMAIL.COM,NY,J\n```\n\n### Selecting specific columns \n\nUsing the same `contacts.csv` [input sample](#input-sample).\n\n```shell\ncsv-tr contacts.csv -o email,state \u003e contact-email-state.csv\n```\n\n`contact-email-state.csv` would look like:\n\n```csv\nemail,state\njuan@gmail.com,FL\nmiguel@hotmail.com,NY\njesus@gmail.com,NY\n```\n\n### Excluding specific columns\n\nUsing the same `contacts.csv` [input sample](#input-sample).\n\n```shell\ncsv-tr contacts.csv -e email,state \u003e contact-names.csv\n```\n\n`contact-names.csv` would look like:\n\n```csv\nname\nJuan\nMiguel\nJesus\n```\n\n### Sorting by column\n\nUsing the same `contacts.csv` [input sample](#input-sample), imagine sorting by `state` -\u003e `DESC` and `name` -\u003e `ASC`:\n\nSorting will guess numeric and date kind of values, and treat them accordingly.\n\n```shell\ncsv-tr contacts.csv -s state:-1,name:1\n```\n\nWould output:\n\n```csv\nname,email,state\nJesus,jesus@gmail.com,NY\nMiguel,miguel@hotmail.com,NY\nJuan,juan@gmail.com,FL\n```\n\n## API Usage\n\nUsing all above's examples at once with the same `contacts.csv` [input sample](#input-sample)\n\n```js\nconst fs = require('fs');\nconst { csvTr, sort, csvStringify } = require('csv-tr');\n\n// un-comment any or multiple of the options below, run it and then take a look at result.csv\ncsvTr(fs.createReadStream('./tests/contacts.csv'), {\n  // filter: (row, index) =\u003e { return /@gmail.com$/i.test(row.email) },\n  // transform: (row, index) =\u003e { row.name = row.name.toUpperCase(); row.email = row.email.toUpperCase(); return row },\n  // only: ['email', 'state'],\n  // exclude: ['email', 'state'],\n}).pipe(csvStringify()).pipe(fs.createWriteStream('result.csv'))\n\n// SORTING\n// mind sorting buffers all rows\nconst csvStreamToSort = csvTr(fs.createReadStream('contacts.csv'))\n\nsort(csvStreamToSort, { state: -1, name: 1 }).then(sortedStream =\u003e {\n  sortedStream.pipe(csvStringify()).pipe(fs.createWriteStream('result-sorted.csv'))\n})\n```\n\n`result-sorted.csv` would look like:\n\n```csv\nname,email,state\nJesus,jesus@gmail.com,NY\nMiguel,miguel@hotmail.com,NY\nJuan,juan@gmail.com,FL\n```\n\n* * *\n\n## License\n\n[MIT](https://opensource.org/licenses/MIT)\n\n\u0026copy; 2021 Martin Rafael \u003ctin@devtin.io\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevtin%2Fcsv-tr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevtin%2Fcsv-tr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevtin%2Fcsv-tr/lists"}