{"id":20089396,"url":"https://github.com/mzimbres/tsvtree","last_synced_at":"2026-03-06T17:35:21.706Z","repository":{"id":81384669,"uuid":"254733370","full_name":"mzimbres/tsvtree","owner":"mzimbres","description":"A command line tool to display TSV data in tree-like format","archived":false,"fork":false,"pushed_at":"2021-06-19T16:37:07.000Z","size":732,"stargazers_count":13,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-06T02:40:08.128Z","etag":null,"topics":["csv","csv-format","csv-parser","tsv","tsv-files","tsv-parser","tsv-utils"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mzimbres.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","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,"zenodo":null}},"created_at":"2020-04-10T20:48:39.000Z","updated_at":"2024-09-14T22:47:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"6a0ce24a-86e7-45c0-a045-96ba36d29147","html_url":"https://github.com/mzimbres/tsvtree","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/mzimbres/tsvtree","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzimbres%2Ftsvtree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzimbres%2Ftsvtree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzimbres%2Ftsvtree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzimbres%2Ftsvtree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mzimbres","download_url":"https://codeload.github.com/mzimbres/tsvtree/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mzimbres%2Ftsvtree/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261786323,"owners_count":23209470,"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":["csv","csv-format","csv-parser","tsv","tsv-files","tsv-parser","tsv-utils"],"created_at":"2024-11-13T16:17:41.302Z","updated_at":"2026-03-06T17:35:16.665Z","avatar_url":"https://github.com/mzimbres.png","language":"C++","readme":"## Description\n\n`tsvtree` is a command line tool to analyse TSV (Tab Separated Value) files. Its main functionalities are\n\n* Visualization of the TSV content in a tree-like format.\n* Compression and serialization.\n* Node information: The number leaf nodes are reachable from an entry and its coordinate in the tree.\n* Support for `TikZ` output format.\n\nIt can be seen as a complement to text processing tools like `awk`, `cut`, `column`, `tac` etc. An example `TikZ` image can be seen below.\n\n![](http://db.occase.de/tsvtree.png)\n\n## Showing the tree\n\nAssume a TSV file like the one in `examples/cities.tsv` shown below\n\n```bash\n$ column examples/cities.tsv -t -s $'\\t'\nEarth  Europe   Western Europe  Germany  Baden-Württemberg    Karlsruhe     Karlsruhe                        Bruchsal\nEarth  America  South America   Brazil   Sudeste              São Paulo     Macro Metropolitana Paulista     Bragança Paulista  Piracaia     Batatuba\nEarth  America  South America   Brazil   Sudeste              São Paulo     Macro Metropolitana Paulista     Bragança Paulista  Atibaia      Alvinópolis\nEarth  Europe   Western Europe  Germany  Baden-Württemberg    Karlsruhe     Rastatt                          Bühl\nEarth  Europe   Western Europe  Germany  Nordrhein-Westfalen  Arnsberg      Ennepe-Ruhr-Kreis                Gevelsberg\nEarth  America  South America   Brazil   Sudeste              São Paulo     Macro Metropolitana Paulista     Bragança Paulista  Atibaia      Jardim Siriema\nEarth  Europe   Western Europe  Germany  Baden-Württemberg    Karlsruhe     Karlsruhe                        Karlsbad\nEarth  America  South America   Brazil   Sudeste              São Paulo     Metropolitana de São Paulo       São Paulo          São Paulo    Mooca\nEarth  America  South America   Brazil   Sudeste              Minas Gerais  Metropolitana de Belo Horizonte  Itabira            Alvinópolis  Alvinópolis\nEarth  America  South America   Brazil   Sudeste              São Paulo     Macro Metropolitana Paulista     Bragança Paulista  Atibaia      Vila Santista\nEarth  Europe   Western Europe  Germany  Nordrhein-Westfalen  Arnsberg      Ennepe-Ruhr-Kreis                Hattingen\nEarth  Europe   Western Europe  France   Grand Est            Elsass        Bas-Rhin                         Strasbourg\nEarth  America  South America   Brazil   Sudeste              Minas Gerais  Metropolitana de Belo Horizonte  Itabira            Alvinópolis  Major Ezequiel\nEarth  Europe   Western Europe  Germany  Baden-Württemberg    Karlsruhe     Rastatt                          Bühlertal\nEarth  Europe   Western Europe  France   Île-de-France        Val-de-Marne  Sucy-en-Brie\nEarth  America  South America   Brazil   Sudeste              São Paulo     Metropolitana de São Paulo       São Paulo          São Paulo    Vila Leopoldina\nEarth  Europe   Western Europe  France   Grand Est            Elsass        Bas-Rhin                         Haguenau\n```\nIt is difficult to see the hierarchical nature of the data by looking at it in this form, also, the redundancy is distracting. `tsvtree` can display it in a much more comprehensible tree-like format as shown below\n\n```bash\n$ tsvtree examples/cities.tsv\nEarth\n├── America\n│   └── South America\n│       └── Brazil\n│           └── Sudeste\n│               ├── Minas Gerais\n│               │   └── Metropolitana de Belo Horizonte\n│               │       └── Itabira\n│               │           └── Alvinópolis\n│               │               ├── Alvinópolis\n│               │               └── Major Ezequiel\n│               └── São Paulo\n│                   ├── Macro Metropolitana Paulista\n│                   │   └── Bragança Paulista\n│                   │       ├── Atibaia\n│                   │       │   ├── Alvinópolis\n│                   │       │   ├── Jardim Siriema\n│                   │       │   └── Vila Santista\n│                   │       └── Piracaia\n│                   │           └── Batatuba\n│                   └── Metropolitana de São Paulo\n│                       └── São Paulo\n│                           └── São Paulo\n│                               ├── Mooca\n│                               └── Vila Leopoldina\n└── Europe\n    └── Western Europe\n        ├── France\n        │   ├── Grand Est\n        │   │   └── Elsass\n        │   │       └── Bas-Rhin\n        │   │           ├── Haguenau\n        │   │           └── Strasbourg\n        │   └── Île-de-France\n        │       └── Val-de-Marne\n        │           └── Sucy-en-Brie\n        └── Germany\n            ├── Baden-Württemberg\n            │   └── Karlsruhe\n            │       ├── Karlsruhe\n            │       │   ├── Bruchsal\n            │       │   └── Karlsbad\n            │       └── Rastatt\n            │           ├── Bühl\n            │           └── Bühlertal\n            └── Nordrhein-Westfalen\n                └── Arnsberg\n                    └── Ennepe-Ruhr-Kreis\n                        ├── Gevelsberg\n                        └── Hattingen\n```\n### Reading from stdin\n\nTo interact with other text processing tools like the ones mentioned above `tsvtree` can also read from standard input. Here are some illustrative examples.\n\n* The authors of the last 50 commits on the linux kernel sorted by date\n```bash\ngit log --oneline --pretty=\"%as%x09%an\" -n 50 | tsvtree\nMaster\n├── 2020-04-09\n│   └── Masahiro Yamada\n├── 2020-04-10\n│   ├── Anshuman Khandual\n│   ├── Arjun Roy\n│   ├── Eric Biggers\n│   ├── Jaewon Kim\n│   ├── Linus Torvalds\n│   ├── Logan Gunthorpe\n│   ├── Pali Rohár\n│   ├── Roman Gushchin\n│   ├── Thomas Gleixner\n│   ├── Vasily Averin\n│   ├── Xiaoyao Li\n│   └── kbuild test robot\n├── 2020-04-11\n│   ├── Linus Torvalds\n│   ├── Sedat Dilek\n│   └── Trond Myklebust\n└── 2020-04-12\n    └── Linus Torvalds\n```\n* Last 40 commits on the linux kernel excluding Linus Torvalds sorted by author.\n\n```bash\ngit log --oneline --pretty=\"%ci%x09%h%x09%s%x09%an\" -n 40 | grep -v Torvalds | awk -F $'\\t' '{print $4\"\\t\"$1\" \"$2\" \"$3}' | tsvtree\nMaster\n├── Eric Biggers\n│   ├── 2020-04-10 15:36:22 -0700 23756e551f35 selftests: kmod: test disabling module autoloading\n│   ├── 2020-04-10 15:36:22 -0700 26c5d78c976c fs/filesystems.c: downgrade user-reachable WARN_ONCE() to pr_warn_once()\n│   └── 2020-04-10 15:36:22 -0700 d7d27cfc5cf0 kmod: make request_module() return an error when autoloading is disabled\n├── Logan Gunthorpe\n│   ├── 2020-04-10 15:36:21 -0700 bfeb022f8fe4 mm/memory_hotplug: add pgprot_t to mhp_params\n│   ├── 2020-04-10 15:36:21 -0700 c164fbb40c43 x86/mm: thread pgprot_t through init_memory_mapping()\n│   └── 2020-04-10 15:36:21 -0700 f5637d3b42ab mm/memory_hotplug: rename mhp_restrictions to mhp_params\n│   └── 2020-04-11 11:42:35 -0400 27d231c0c63b pNFS: Fix RCU lock leakage\n├── Vasily Averin\n│   ├── 2020-04-10 15:36:22 -0700 3bfa7e141b0b fs/seq_file.c: seq_read(): add info message about buggy .next functions\n│   ├── 2020-04-10 15:36:22 -0700 89163f93c6f9 ipc/util.c: sysvipc_find_ipc() should increase position index\n│   └── 2020-04-10 15:36:22 -0700 f4d74ef6220c kernel/gcov/fs.c: gcov_seq_next() should increase position index\n└── Xiaoyao Li\n    ├── 2020-04-11 16:40:55 +0200 9de6fe3c28d6 KVM: x86: Emulate split-lock access as a write in emulator\n    └── 2020-04-11 16:42:41 +0200 e6f8b6c12f03 KVM: VMX: Extend VMXs #AC interceptor to handle split lock #AC in guest\n```\n* Last access time on each file of an arbitrary repository in th form `root:month:day`. \n\n```bash\n$ find  . -name *.cpp -printf \"%Tm\\t%Td\\t%f\\n\" | tsvtree\nRoot\n├── 01\n│   ├── 06\n│   │   ├── redis.cpp\n│   │   └── test_clients.cpp\n│   └── 09\n│       ├── notify-test.cpp\n│       └── mms.cpp\n├── 02\n│   ├── 01\n│   │   ├── db.cpp\n│   │   └── key-gen.cpp\n│   ├── 11\n│   │   └── crypto.cpp\n│   └── 12\n│       ├── mms_session.cpp\n│       └── post.cpp\n├── 04\n│   └── 06\n│       └── json.cpp\n└── 12\n    ├── 18\n    │   ├── db_tests.cpp\n    │   ├── logger.cpp\n    │   ├── net.cpp\n    │   └── system.cpp\n    ├── 28\n    │   ├── notifier.cpp\n    │   ├── ntf_session.cpp\n    │   └── notify.cpp\n    └── 31\n        └── sim.cpp\n\n```\n\n### Restricting the depth\n\nFor large files it is sometimes useful to restrict the output to a certain depth in the tree. As an example let us run `tsvtree` on file [this](https://github.com/mzimbres/trees/blob/master/worldcities.tree.comp.tsv) file that contains all cities in the world restricting the output depth to 2\n\n```bash\n$ tsvtree --tree --depth 2  worldcities.comp\nPlaces\n├── Africa\n│   ├── Northern Africa\n│   ├── Eastern Africa\n│   ├── Middle Africa\n│   ├── Southern Africa\n│   └── Western Africa\n├── America\n│   ├── Caribbean\n│   ├── Central America\n│   ├── South America\n│   └── Northern America\n├── Asia\n│   ├── Central Asia\n│   ├── Eastern Asia\n│   ├── South-eastern Asia\n│   ├── Southern Asia\n│   └── Western Asia\n├── Europe\n│   ├── Northern Europe\n│   ├── Eastern Europe\n│   ├── Southern Europe\n│   └── Western Europe\n└── Oceania\n    ├── Autralia and New Zealand\n    ├── Melanesia\n    ├── Micronesia\n    └── Polynesia\n```\nThe `.comp` format will be explained below.\n\n## Compressing the tree\n\nTSV files like the one above have a lot of redundancy since the nodes at small depths appear many times in the file. With `tsvtree` it is possible to compress the file by using numbers to represent the depth of the tree. The resulting file can be more than five times smaller then the original TSV\n\n```bash\n$ tsvtree --output comp examples/cities.tsv \n0\tRoot\n1\tBrazil\n2\tRio de Janeiro\n3\tRio de Janeiro\n3\tTeresópolis\n2\tSao Paulo\n3\tAtibaia\n3\tSao Paulo\n1\tFrance\n2\tAlsacia\n3\tHagenau\n3\tStrasburg\n2\tÎle-de-France\n3\tParis\n3\tSucy-en-Brie\n1\tGermany\n2\tBaden-würtemberg\n3\tKarlsruhe\n3\tStuttgart\n2\tNordrhein-Westphalen\n3\tDüsseldorf\n3\tKöln\n```\n\nThe file `worldcities.comp` in the compressed format has the 456 kbytes in size whereas the same data in TSV format has 2064 kbytes, namely more that five times larger. To decompress it again to either TSV or tree format run\n\n```bash\n$ tsvtree --tree --output tsv worldcities.comp\n$ tsvtree --tree --output tree worldcities.comp\n```\nCompressing the data in this form with `gzip` or other compressing tools also produces better results than compressing the original TSV directly. \n\n## Leaf counters and node coordinate\n\nOnce the tree in `.comp` format is available it is possible to show some useful information about the nodes at a specific depth, such as the number of leaf nodes that are reachable from each node in the tree and their coordinate in the tree. For example\n\n```bash\n$ tsvtree --tree --depth 2 --output info worldcities.comp | column -t -s $'\\t'\nNorthern Africa           000.000  99\nEastern Africa            000.001  109\nMiddle Africa             000.002  70\nSouthern Africa           000.003  219\nWestern Africa            000.004  143\nCaribbean                 001.000  102\nCentral America           001.001  226\nSouth America             001.002  11444\nNorthern America          001.003  366\nCentral Asia              002.000  42\nEastern Asia              002.001  1358\nSouth-eastern Asia        002.002  380\nSouthern Asia             002.003  437\nWestern Asia              002.004  206\nNorthern Europe           003.000  829\nEastern Europe            003.001  2039\nSouthern Europe           003.002  1215\nWestern Europe            003.003  46532\nAutralia and New Zealand  004.000  111\nMelanesia                 004.001  77\nMicronesia                004.002  10\nPolynesia                 004.003  14\n```\nIf your TSV file does not have the root node on the left and the leaf nodes on the right, you will have to reorder it. This can be easily achieved with `awk`, for example\n\n```bash\nawk -F$'\\t' '{print $3\":\"$2\":\"$1}' file.tsv\n```\nwill select columns 1, 2, and 3 of `file.tsv` and reverse them.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmzimbres%2Ftsvtree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmzimbres%2Ftsvtree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmzimbres%2Ftsvtree/lists"}