web-dev-qa-db-ja.com

特別な拡張可能なフレーズをbashで作成する方法は?

私は毎日非常に頻繁に<command> --help | grep <feature>をしています。 ^^のように"--help | grep"に展開できるものを作成することが可能かどうか疑問に思っていました。

ls ^^ size

それは以下を実行します:

ls --help | grep size
12

zshでは、globalエイリアスを使用します。

$ 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)

bashを使用すると、history Expansionを使用できる場合があります。これは、シェル構文解析の早い段階で発生し、パイプの置換で機能する可能性があります。

  1. 置換したいテキストと、他の方法では使用する可能性が低い特殊文字(ここでは、たまたまキーボードにある£のような)を使用して、履歴を準備します。

     $ --help $(: £)|grep
     bash: --help: command not found
     Usage: grep [OPTION]... PATTERN [FILE]...
     Try 'grep --help' for more information.
    
  2. 次に、履歴拡張を使用してそれを取得します。

    $ 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
    

または、いくつかのキーまたはキーシーケンスを押したときにreadline--help|grepを展開させることができます。これをbashのみに適用するには(およびreadlineを使用してgdbのような他のアプリケーションには適用しない)、bindのAPIであるbash bash組み込みコマンドを使用できます。 readlineを設定するには、たとえば~/.bashrcで:

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

または、~/.inputrc(readlineの構成ファイル)に追加します。

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

(readlineを使用するrcesのような他のシェルがあり、そのバインドを行うことが理にかなっているが、AFAICTでは、readlineを呼び出す前にrl_readline_name変数を設定しないため、それらにいくつかの$ifステートメントを追加することはできません(アプリケーション名を知らせずにreadlineを使用するすべてのアプリケーションのようにotherとして表示されます))。

置換が行われるためには、最初の値のあと0.5秒以内(デフォルト)に2番目の^を入力する必要があることに注意してください。

15

あなたはそのためにbash関数を使うことができます:

以下を〜/ .bashrcに入れてください:

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

bashrcを保存するときはsource ~/.bashrcその後、次のことができます。

$ 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
17
tgwtdt

Readlineバインディングを使用できます。

のような行を追加

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

〜/ .inputrc

次に、用語で^ X ^ Rを押すと、バインディングがアクティブになります。

ls ^^を入力すると、ls --help | grepになります。

8
Alex Stragies

@tgwtdtによるソリューションが気に入ったので、少し拡張しました。

これは同じことを行いますが、エラーを処理するために少し行い、組み込みを処理しようとします。

qhは{}ではなく()を使用するため、qh1()とoutはローカルです(サブシェル内)。

function qh () (
    function qh1 () {
      out="$(help "$1" 2>&1 )"
      [ $? -ne 0 ] && return 1
      echo "$out"
    }

    type -all "$1" ; { qh1 "$1" || "$1" --help 2>/dev/null || man "$1" 2>/dev/null ;} | egrep -i -- "$2"
) 
3
Joe