{"id":21002750,"url":"https://github.com/200ok-ch/oktags","last_synced_at":"2025-07-16T08:33:15.016Z","repository":{"id":55423899,"uuid":"304010699","full_name":"200ok-ch/oktags","owner":"200ok-ch","description":"Manage tags on plain old files","archived":false,"fork":false,"pushed_at":"2025-01-06T10:07:27.000Z","size":92,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-04T14:38:17.997Z","etag":null,"topics":["commandline","filesystem","ruby","tagging"],"latest_commit_sha":null,"homepage":"https://200ok.ch","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/200ok-ch.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"zenodo":null},"funding":{"github":["200ok-ch"]}},"created_at":"2020-10-14T12:38:59.000Z","updated_at":"2025-01-06T10:07:31.000Z","dependencies_parsed_at":"2025-05-15T00:47:47.276Z","dependency_job_id":null,"html_url":"https://github.com/200ok-ch/oktags","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/200ok-ch/oktags","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/200ok-ch%2Foktags","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/200ok-ch%2Foktags/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/200ok-ch%2Foktags/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/200ok-ch%2Foktags/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/200ok-ch","download_url":"https://codeload.github.com/200ok-ch/oktags/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/200ok-ch%2Foktags/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265497485,"owners_count":23776997,"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":["commandline","filesystem","ruby","tagging"],"created_at":"2024-11-19T08:19:50.945Z","updated_at":"2025-07-16T08:33:14.989Z","avatar_url":"https://github.com/200ok-ch.png","language":"Ruby","funding_links":["https://github.com/sponsors/200ok-ch"],"categories":[],"sub_categories":[],"readme":"#+begin_example\n       _    _\n  ___ | | _| |_ __ _  __ _ ___\n / _ \\| |/ / __/ _` |/ _` / __|\n| (_) |   \u003c| || (_| | (_| \\__ \\\n \\___/|_|\\_\\\\__\\__,_|\\__, |___/\n                     |___/\n#+end_example\n\n#+html: \u003cimg src=\"https://github.com/200ok-ch/oktags/workflows/CI/badge.svg\"/\u003e\n#+html: \u003ca href=\"https://rubygems.org/gems/oktags\"\u003e \u003cimg src=\"https://badge.fury.io/rb/oktags.svg\"/\u003e\u003c/a\u003e\n\n* NAME\n\n=oktags= - manage tags on plain old files\n\n* SYNOPSIS\n\n  #+begin_example\n    Usage: oktags [options]\n        -a, --add-tags TAGS FILE         Add comma-separated TAGS to FILE\n        -d TAG FILE,                     Delete TAG from FILE\n            --delete-tag-from-file\n        -i FILE,                         Auto-complete tags and add them to FILE\n            --add-tags-interactively\n        -l, --list [PATH]                List file tags (optional PATH)\n        -r, --rename-tag OLD_TAG NEW_TAG Rename OLD_TAG to NEW_TAG(S) recursively for all files\n        -s TAGS [PATH],                  Search files which include (comma-separated) tags recursively (optional PATH)\n            --search-files-with-tags\n  #+end_example\n\n* DESCRIPTION\n\n=oktags= helps you organize your files by managing tags on them. It\nworks by adding/removing at the end of the filename. Given a file\n=cat.jpg=, when adding the tags =tag1= and =tag2=, the filename will\nbecome =cat--[tag1,tag2].jpg=. The implementation is OS-agnostic, so\nit should work on Linux, macOS and Windows.\n\n* EXAMPLES\n\nAdd tags to a file. Tags are always unique.\n\n#+begin_example\n  $ touch foobar\n  $ oktags -a tag1 foobar\n  $ ls foobar*\n  foobar--[tag1]\n  $ oktags -a tag2 foobar--\\[tag1\\]\n  $ ls foobar*\n  foobar--[tag1,tag2]\n  $ oktags -a tag3,tag2 foobar--[tag1,tag2].pdf\n  $ ls foobar*\n  foobar--[tag1,tag2,tag3].pdf\n#+end_example\n\nDelete a tag from a file.\n\n#+begin_example\n  $ find . | grep business_card | head -n 1\n  ./archiv/Reto_Huber--[business_card,somedia,seo].pdf\n  $ oktags -d seo ./archiv/Reto_Huber--[business_card,somedia,seo].pdf\n  $ find . | grep business_card | head -n 1\n  ./archiv/Reto_Huber--[business_card,somedia].pdf\n#+end_example\n\nInteractively add tags (with auto-completion through readline) to a file.\n\n#+begin_example\n  $ oktags -i foo\n  \u003e t[TAB]\n  tag1  tag2  tag3\n  \u003e tag2, new tag\n  $ ls foo* | grep new\n  foo--[new_tag,tag2]\n#+end_example\n\nList all tags in the current folder.\n\n#+begin_example\n  $ touch foo\n  $ touch bar.txt\n  $ touch foobar--[tag1,tag2].pdf\n  $ touch baz--[tag1].txt\n  $ oktags -l\n  tag1(2)\n  tag2(1)\n#+end_example\n\nList all tags for a given path glob (assuming the same data set as above).\n\n#+begin_example\n  $ oktags -l '*txt'\n  tag1(1)\n#+end_example\n\nRename tag.\n\n#+begin_example\n  $ oktags -l\n  200ok_expense(8)\n  business_card(4)\n  $ oktags -r 200ok_expense 200ok,expense\n  $ oktags -l\n  expense(8)\n  200ok(8)\n  business_card(4)\n#+end_example\n\nSearch files with tags.\n\n#+begin_example\n  $ oktags -s somedia,seo,business_card\n  archiv/Reto_Huber--[business_card,seo,somedia].pdf\n  archiv/Reto_Huber--[business_card,seo,somedia].txt\n  $ oktags -s business_card '**/*pdf'\n  archiv/Reto_Huber--[business_card,seo,somedia].pdf\n  archiv/Stefan_Schmidt--[business_card,lawoon].pdf\n#+end_example\n\n* INSTALLATION\n\n=oktags= is implemented in [[https://www.ruby-lang.org/en/][Ruby]] and can be installed as a [[https://rubygems.org/][gem]].\n\n  #+begin_example\n    gem install oktags\n  #+end_example\n\n* DEVELOPMENT\n\n=oktags= is implemented in [[https://www.ruby-lang.org/en/][Ruby]], dependencies are managed with [[https://bundler.io/][bundler]].\n\nAfter checking out the repo, run =bin/setup= to install dependencies.\nYou can also run =bin/console= for an interactive prompt that will\nallow you to experiment.\n\nTo install this gem onto your local machine, run =bundle exec rake\ninstall=. To publish a new version, update the version number in\n=version.rb=, and then run =bundle exec rake publish=, which will\ncreate a git tag for the version, push git commits and tags, and push\nthe =.gem= file to [[https://rubygems.org][rubygems.org]].\n\n* TESTS\n\nTests are implemented with [[https://rspec.info/][RSpec]] and can be run with =bundle exec\nrspec spec=.\n\n* NOTES\n\nSoftware systems come and go. It is easy to lose important data in\n(proprietary) legacy systems. Plain old files are boring and are\ntherefore here to stay; at least they [[https://en.wikipedia.org/wiki/Computer_file#Storage][have been around since 1961]].\nAdditional benefits of using plain old files are:\n\n- They are (mostly) platform independent.\n- They can be accessed by a wide array of software\n  - They do not require a specific UI.\n  - They do not require the use a database (apart from the filesystem\n    itself, of course).\n- They can be transported independently from the software that captured/created them.\n- They are not proprietary.\n\n=oktags= is decidedly built to be just as boring as plain old files.\nIt's written in a language that's been proven for shell scripts ([[https://www.ruby-lang.org/en/][Ruby]])\nrather than using something more 'cool'/'interesting'. It also only\nuses Ruby built-ins and has no dependencies when run as a CLI or\nlibrary. =oktags= is therefore boring and here to stay. The idea is to\ntag your files once and for all, so you will not loose your important\ndata in something that will become an unsupported legacy system at\nsome point.\n\nAt [[https://200ok.ch/][200ok]], we develop various Free Software projects that work on plain\nold files:\n\n- [[https://github.com/200ok-ch/organice/][organice]]: An implementation of Org mode without the dependency of\n  Emacs - built for mobile and desktop browsers.\n- [[https://github.com/200ok-ch/okdoc][okdoc]]: A document scanning and archiving solution (which works well\n  with =oktags=).\n\n\n* SEE ALSO\n\n[[http://tmsu.org/][tmsu]], [[https://www.tagspaces.org/][tagspaces]]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F200ok-ch%2Foktags","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F200ok-ch%2Foktags","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F200ok-ch%2Foktags/lists"}