{"id":13753906,"url":"https://github.com/learnbyexample/command_help","last_synced_at":"2025-10-12T08:30:17.441Z","repository":{"id":56781677,"uuid":"74438672","full_name":"learnbyexample/command_help","owner":"learnbyexample","description":":information_source: Extract help text from builtin commands and man pages","archived":false,"fork":false,"pushed_at":"2024-08-01T10:11:12.000Z","size":24,"stargazers_count":96,"open_issues_count":1,"forks_count":9,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-01-21T17:06:56.366Z","etag":null,"topics":["bash","command","help"],"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/learnbyexample.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,"publiccode":null,"codemeta":null}},"created_at":"2016-11-22T05:45:56.000Z","updated_at":"2024-11-22T14:35:56.000Z","dependencies_parsed_at":"2024-10-23T01:47:47.901Z","dependency_job_id":null,"html_url":"https://github.com/learnbyexample/command_help","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnbyexample%2Fcommand_help","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnbyexample%2Fcommand_help/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnbyexample%2Fcommand_help/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnbyexample%2Fcommand_help/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/learnbyexample","download_url":"https://codeload.github.com/learnbyexample/command_help/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236184421,"owners_count":19108672,"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":["bash","command","help"],"created_at":"2024-08-03T09:01:33.865Z","updated_at":"2025-10-12T08:30:17.128Z","avatar_url":"https://github.com/learnbyexample.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# \u003ca name=\"command-help\"\u003e\u003c/a\u003eCommand Help\n\n* [Examples](#examples)\n* [Known Issues](#known-issues)\n* [Contributing](#contributing)\n* [Wish list](#wish-list)\n* [Basic one-liner script](#one-liner)\n* [License](#license)\n\nInspired by [explainshell](http://explainshell.com/), tried out a `bash` script as a learning exercise. Tested only with **Ubuntu 16.04 LTS**. This is a simple single command search, many features like multiple commands in a pipe, command substitution, etc not implemented\n\n\u003cbr\u003e\n\n**A few learnings from this exercise**\n\n* Optimizing the code - had recently read [good taste coding](https://medium.com/@bartobri/applying-the-linus-tarvolds-good-taste-coding-requirement-99749f37684a#.tlduyaygx) and it so happened that I too was able to remove some conditionals\n* Initially, I had different code for extracting text for `builtin` commands and `man` pages (a case of [DRY](https://en.wikipedia.org/wiki/Don't_repeat_yourself)), then was able to combine into unified code\n* Saving output of `help` or `man` into a file and using it when needed proved faster\n* Check out [earlier versions of the script](https://github.com/learnbyexample/command_help/commits/master/ch) for a snapshot of how things unfolded\n\n\u003cbr\u003e\n\n### \u003ca name=\"examples\"\u003e\u003c/a\u003eExamples\n\nCalling by simple `ch` works for me as the script has been added to a `PATH` directory  \nSee [Bash Scripting tutorial](https://ryanstutorials.net/linuxtutorial/scripting.php) for an introduction on `bash` scripting and how to execute it\n\n* Single letter option\n\n```bash\n$ ch column -t\n     column — columnate lists\n\n     -t      Determine the number of columns the input contains and create a table.  Columns are delimited with\n             whitespace, by default, or with the characters supplied using the -s option.  Useful for pretty-printing\n             displays.\n             \n$ ch cd -P\n    cd - Change the shell working directory.\n\n        -P\tuse the physical directory structure without following symbolic\n    \tlinks: resolve symbolic links in DIR before processing instances\n    \tof `..'\n```\n\n* Multiple single letter options\n\n```bash\n$ ch ls -latrh\n       ls - list directory contents\n\n       -l     use a long listing format\n\n       -a, --all\n              do not ignore entries starting with .\n\n       -t     sort by modification time, newest first\n\n       -r, --reverse\n              reverse order while sorting\n\n       -h, --human-readable\n              with -l and/or -s, print human readable sizes (e.g., 1K 234M 2G)\n\n```\n\n* Long options\n\n```bash\n$ ch ls --author\n       ls - list directory contents\n\n       --author\n              with -l, print the author of each file\n\n$ ch grep --color=auto\n       grep, egrep, fgrep, rgrep - print lines matching a pattern\n\n       --color[=WHEN], --colour[=WHEN]\n              Surround the matched (non-empty) strings, matching lines, context lines, file names, line numbers, byte\n              offsets, and separators (for fields and groups of context lines) with escape sequences to display  them\n              in  color  on  the  terminal.   The  colors  are  defined by the environment variable GREP_COLORS.  The\n              deprecated environment variable GREP_COLOR is still supported, but its setting does not have  priority.\n              WHEN is never, always, or auto.\n\n$ ch grep --regexp\n       grep, egrep, fgrep, rgrep - print lines matching a pattern\n\n       -e PATTERN, --regexp=PATTERN\n              Use PATTERN as the pattern.  If this option is used multiple times or is combined with the -f  (--file)\n              option,  search  for  all  patterns given.  This option can be used to protect a pattern beginning with\n              “-”.\n```\n\n* Multiple character option with single -\n\n```bash\n$ ch find -mtime\n       find - search for files in a directory hierarchy\n\n       -mtime n\n              File's  data  was last modified n*24 hours ago.  See the comments for -atime to understand how rounding\n              affects the interpretation of file modification times.\n```\n\n* `man` pages with short and long option both starting with single -\n\n```bash\n$ ch rename -verbose -n\n       rename - renames multiple files\n\n       -v, -verbose\n               Verbose: print names of files successfully renamed.\n       -n, -nono\n               No action: print names of files to be renamed, but don't rename.\n```\n\n* Multiple arguments\n\n```bash\n$ ch grep -l -ro\n       grep, egrep, fgrep, rgrep - print lines matching a pattern\n\n       -l, --files-with-matches\n              Suppress normal output; instead print the name of each input file from which output would normally have\n              been printed.  The scanning will stop on the first match.\n       -r, --recursive\n              Read  all  files  under  each  directory, recursively, following symbolic links only if they are on the\n              command line.  Note that if no file operand is given, grep searches the  working  directory.   This  is\n              equivalent to the -d recurse option.\n\n       -o, --only-matching\n              Print  only  the matched (non-empty) parts of a matching line, with each such part on a separate output\n              line.\n```\n\n* Short and Long options spread over two lines\n\n```bash\n$ ch wget -o\n       Wget - The non-interactive network downloader.\n\n       -o logfile\n       --output-file=logfile\n           Log all messages to logfile.  The messages are normally reported to standard error.\n```\n\n* Word search\n\n```bash\n$ ch grep 'exit status'\n       grep, egrep, fgrep, rgrep - print lines matching a pattern\n\n              file name wildcard expansion and therefore  should  not  be  treated  as  options.   This  behavior  is\n              available only with the GNU C library, and only when POSIXLY_CORRECT is not set.\n\nEXIT STATUS\n       Normally  the exit status is 0 if a line is selected, 1 if no lines were selected, and 2 if an error occurred.\n       However, if the -q or --quiet or --silent is used and a line is selected, the exit status  is  0  even  if  an\n       error occurred.\n\nCOPYRIGHT\n\n$ ch sed NUL\n       sed - stream editor for filtering and transforming text\n\n\n       -z, --null-data\n\n              separate lines by NUL characters\n\n       --help\n              display this help and exit\n```\n\n\u003cbr\u003e\n\n### \u003ca name=\"known-issues\"\u003e\u003c/a\u003eKnown Issues\n\n* option description spread over multiple lines\n\n```bash\n$ ch find -type\n       find - search for files in a directory hierarchy\n\n       -type c\n              File is of type c:\n              \n$ # ideally, it should be\n       find - search for files in a directory hierarchy\n       \n       -type c\n              File is of type c:\n\n              b      block (buffered) special\n\n              c      character (unbuffered) special\n\n              d      directory\n\n              p      named pipe (FIFO)\n\n              f      regular file\n\n              l      symbolic link; this is never true if the -L option or the -follow option is  in  effect,  unless\n                     the symbolic link is broken.  If you want to search for symbolic links when -L is in effect, use\n                     -xtype.\n\n              s      socket\n\n              D      door (Solaris)\n```\n\n* special characters\n\n```bash\n$ # should have extracted only option line\n$ ch printf %b\n    printf - Formats and prints ARGUMENTS under control of the FORMAT.\n\n      %b\texpand backslash escape sequences in the corresponding argument\n      %q\tquote the argument in a way that can be reused as shell input\n      %(fmt)T output the date-time string resulting from using FMT as a format\n            string for strftime(3)\n```\n\n* option matching text of another option description\n\n```bash\n$ # depends on width of terminal, this issue seen on 120 as width\n$ ch sort -V\n       sort - sort lines of text files\n\n              -V\n\t      \n$ # the issue is because another line happened to start with `-V` before the `-V` option definition\n$ ch sort version-sort\n       sort - sort lines of text files\n\n              sort  according to WORD: general-numeric -g, human-numeric -h, month -M, numeric -n, random -R, version\n              -V\n\n       -V, --version-sort\n              natural sort of (version) numbers within text\n\n       Other options:\n```\n\n\u003cbr\u003e\n\n### \u003ca name=\"contributing\"\u003e\u003c/a\u003eContributing\n\n* Please open an issue for typos/bugs/suggestions/etc\n    * **Even for pull requests, open an issue for discussion before submitting PRs**\n* Share the repo with friends/colleagues, on social media, etc to help reach other learners\n* In case you need to reach me, mail me at `echo 'bGVhcm5ieWV4YW1wbGUubmV0QGdtYWlsLmNvbQo=' | base64 --decode` or send a DM via [twitter](https://twitter.com/learn_byexample)\n\n\u003cbr\u003e\n\n### \u003ca name=\"wish-list\"\u003e\u003c/a\u003eWish list\n\n* Script to automatically check that newer changes don't break working cases (Done)\n* Error message for wrong usage (command not found done)\n* Colored/Formatted output\n* Extract section wise\n* Edge cases\n\t* **\\a** ; **%%** etc for `printf`\n\t* **-f, -force** ; **-n, -nono** etc for `perl` based `rename` (Done)\n* Command examples\n* Try out [groff](https://unix.stackexchange.com/questions/15855/how-to-dump-a-man-page/15859#15859) as suggested by [@Wildcard](https://unix.stackexchange.com/users/135943/wildcard)\n* Portable script to work on different flavors of Linux, possibly Unix variants too\n\n\u003cbr\u003e\n\n### \u003ca name=\"one-liner\"\u003e\u003c/a\u003eBasic one-liner script\n\nWas using this simple function for single option search until this script:\n\n```bash\n$ ch() { whatis $1; man $1 | sed -n \"/^\\s*$2/,/^$/p\" ; }\n\n$ ch grep -l\ngrep (1)             - print lines matching a pattern\n       -l, --files-with-matches\n              Suppress normal output; instead print the name of each input file from which output would normally have\n              been printed.  The scanning will stop on the first match.\n\n$ ch ls -v\nls (1)               - list directory contents\n       -v     natural sort of (version) numbers within text\n```\n\nThere is also a command-line implementation called [explain](https://github.com/andysalerno/explain) which works from command line but not as well as **explainshell**\n\n\u003cbr\u003e\n\n### \u003ca name=\"license\"\u003e\u003c/a\u003eLicense\n\nThis work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flearnbyexample%2Fcommand_help","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flearnbyexample%2Fcommand_help","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flearnbyexample%2Fcommand_help/lists"}