How to make a special expandable phrase in bash?

You can use a bash function for that:

Put the following in your ~/.bashrc:

qh() {
    type -all "$1" ; { man "$1" || "$1" --help ;} | egrep -i -- "$2"
}

When you save your bashrc do source ~/.bashrc then you can do:

$ qh ls size
      --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                               '--block-size=M' prints sizes in units of
  -h, --human-readable       with -l and/or -s, print human readable sizes
  -s, --size                 print the allocated size of each file, in blocks
  -S                         sort by file size, largest first
      --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
  -T, --tabsize=COLS         assume tab stops at each COLS instead of 8

With zsh, you'd use a global alias:

$ alias -g '^^=--help|grep --color -i'
$ ls ^^ size
     --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
                              1,048,576 bytes; see SIZE format below
 -h, --human-readable       with -l and/or -s, print human readable sizes
 -s, --size                 print the allocated size of each file, in blocks
 -S                         sort by file size, largest first
     --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
 -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
The SIZE argument is an integer and optional unit (example: 10K is 10*1024)

With bash, you may be able to use history expansion which is one that happens early enough in the shell syntax parsing that it can work at substituting a pipe:

  1. Prime the history with a the text you want to substitute and a special character you're unlikely to use otherwise (like £ here that happens to be on my keyboard):

     $ --help $(: £)|grep
     bash: --help: command not found
     Usage: grep [OPTION]... PATTERN [FILE]...
     Try 'grep --help' for more information.
    
  2. Then using history expansion to retrieve that:

    $ ls !?£? size
    ls --help $(: £)|grep size
         --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
     -h, --human-readable   with -l and/or -s, print human readable sizes
     -s, --size             print the allocated size of each file, in blocks
     -S                     sort by file size, largest first
         --sort=WORD        sort by WORD instead of name: none (-U), size (-S),
     -T, --tabsize=COLS     assume tab stops at each COLS instead of 8
    

Or you could have readline expand --help|grep upon some key or key sequence press. For that to apply to bash only (and not other applications like gdb using readline), you can use the bind bash builtin command which is bash's API to configuring readline, for instance in your ~/.bashrc:

bind '"^^": "--help|grep "'

Or add to your ~/.inputrc (readline's configuration file):

$if Bash
"^^": "--help|grep "
$endif

(there are other shells like rc or es that use readline and where doing that binding could make sense but AFAICT, they do not set the rl_readline_name variable before invoking readline so you won't be able to add some $if statements for them (they would show as other like all applications that use readline without telling it their application name)).

Note that you need to enter the second ^ within half a second (by default) after the first one for the substitution to occur.


You could use readline bindings:

add a line like

"^^": "--help | grep "

to your ~/.inputrc

Then press ^X ^R in your term, and the binding will be activated.

Keying ls ^^ will now result in ls --help | grep.