web-dev-qa-db-ja.com

引数の順序をすばやく変更できるシェルはありますか?

私はコマンドラインを多用し、長年にわたってbashからzshに毎日のドライバーシェルとして移行しています。通常、少しカスタマイズしたoh-my-zsh環境を使用しますが、一部のシステムはpreztoにあります。違いは大きくありません。

私がzshに使用している最も生産的なプラグインはzsh-syntax-highlightinghistory-substring-searchで、最近、履歴を取得するために非常に強力なfzfプラグインを使用しています。

今、私はコマンドラインで私にとって残っている最大の問題点の1つをコマンド引数の並べ替えです。かなり頻繁に私はコマンドを実行しようとします

command very/long/filesystem/path/to/argumentA another/filesystem/or/network/path/argumentB

順序が逆になっていることに気づきます。

もう1つのより一般的な状況は、「手動展開」ワークフローを実行する場合です。最初に、新しいものを実際のものと比較します。

diff /opt/app/static/www/a.html /home/user/docs/dev/src/a.html
cp /home/user/docs/dev/src/a.html /opt/app/static/www/a.html

OK、OK、最後の例、これ以上約束しない。ここに完璧な現実世界の例があります。人間サイズの甘いファイルリストをいくつか見てみましょう。

find /pool/backups -type f -print0 | xargs -0 ls -lh > filelisting

サイズを並べ替えて選びたい:

sort -rhk5 filelisting | fzf -m > /these/are/the_chosen

うまくいきました!ああ、でもここにパスが必要です:

cut -d ' ' -f 10 /these/are/the_chosen

出力はガベージです。ls -lhでセットバックが発生し、スペースが必要になります。しかし、再グループ化する準備ができています。隣接するスペースに参加します。 tr -sを選択して、スペース文字を絞り込みます。ここでは正規表現は必要ありません。ただし、trにはstdinが必要です。

cat /these/are/the_chosen | tr -s ' ' | cut -d ' ' -f 9- > filelist

ここでは、すでにカットアンドペーストで苦痛を感じています。ここでの私の選択は常に厄介な選択肢の間にあります。長いパスを移動したり、カットコマンドを移動したりできます。どちらの移動でも、マウスがそれをコピーできるように手を伸ばすか、新しい場所にもう一度入力する必要があります。勝てない。コマンドラインを使用すると、移動するのも面倒であり、Word Hopsホットキーを設定しないと非常に面倒です。マウスを使ってすばやくジャンプすることすらできません。だから、thisは私が廃止したい非効率です。モンスターパイプラインのプロトタイプを作成している間、シェルオブジェクト(有効なパス文字列など)をつかむ手間を省き、自由に左右に動かしたいと思います。その機能があれば、5回スパムしてcut&フラグの左側にパスを突き出し、残りのパイプラインを有機的に構築できます。

ここで問題となっているのは、ライン編集力の欠如です。最も簡単な転置の例では、おそらくcptoを呼び出して引数を反転し、作業をcpコマンドにパントする簡単なシェルスクリプトを作成できます。しかし、私はそれをする必要はありません、そしてそれは3番目の例のために私を助けません。

sideways のようなプラグインを使用してVimにいる場合、さまざまなタイプのリストに対して実行できるように、単純なキーの組み合わせを使用して入力した引数を並べ替えることができるようにしたいと思います。

そのようなプラグインはzshに存在しますか?そのようなプラグインは他のシェルに存在しますか?

そうでない場合、zshの実装はどれほど難しいでしょうか? zsh-syntax-highlightingプラグインは、引数をトークン化することが可能であることを証明していると思います。実際、シェルは履歴から個々の引数を取得する方法を知っています: https://stackoverflow.com/a/21439621/340947

問題点は非常に厳しく、一般的であるため、履歴の最後のエントリを取得して最後の2つの引数を交換するホットキーにバインドして実行する簡単なスクリプトを作成する傾向があります。ただし、コマンドの実行をコミットするのではなく、対話的にスワップを実行できるように、ラインエディタ操作を使用するほど理想的ではありません。

おそらく!:0 !:2 !:1を注入することで改善される可能性があります(zshがうまく自動拡張します)が、これにも多くの問題があります。間違ったコマンドを入力した後で自分自身をキャッチした後で引数を交換したい時間の半分以上、そして(2)そのスニペットが説明に失敗する使用されたフラグがしばしばあります。

私はまた、示されているアプローチを見ました here これは問題ありませんが、長いパスではキーストロークを何度も繰り返す必要があるため、非常に満足できません。 Ctrl + Wで削除されたものの。基本的に役に立たない。

完全を期すために、現在取られている戦術は、適切なキーの組み合わせを使用して単語を削除し、コマンドの短い方を削除して並べ替え、カーソルの位置を変更し、マウスを使用して削除された引数を端末出力からコピーし、貼り付けます。 。普通の人はこれに目を向けませんが、コンピューターが私のためにこのタスクを実行するのがどれほど簡単か、そして私が感じる不正義について考えるのを止めることができないので、私はそれをするたびに少し死んでしまいますマウスに手を伸ばさなければならない。

11
Steven Lu

zshでは、デフォルトで動作するすべてのウィジェットwordsを含み、デフォルトで_transpose-words_をバインドします。 Alt+Temacsモードでは、alnum + _$WORDCHARS_文字のシーケンスとして定義されている単語で機能します。

_$WORDCHARS_のデフォルト値には*?_-.[]~=/&;!#$%^(){}<>が含まれるため、_/_が含まれるため、これらのパスが変換しない限り、pathsを転置しても問題ありません。それ以外の文字を含めます。 _:_、_@_、_,_...などが含まれているパスや引用符で囲まれているパスでは機能しません。

ただし、_select-Word-style_フレームワークを使用してWordの定義をオンデマンドで変更できます。

追加した場合:

_autoload -U select-Word-style
zle -N select-Word-style
bindkey '\ez' select-Word-style
_

_~/.zshrc_に、次に押すと Alt+Z、あなたは選択肢を得るでしょう:

_Word styles (hit return for more detail):
(b)ash (n)ormal (s)hell (w)hitespace (d)efault (q)uit
(B), (N), (S), (W) as above with subword matching
?
_

"return for more detail"を押した後:

_(b)ash:       Word characters are alphanumerics only
(n)ormal:     Word characters are alphanumerics plus $WORDCHARS
(s)hell:      Words are command arguments using Shell syntax
(w)hitespace: Words are whitespace-delimited
(d)efault:    Use default, no special handling (usually same as `n')
(q)uit:       Quit without setting a new style
_

とても押す Stranspose 2つのシェルワード(引用符で囲まれたスペースまたはコマンド置換を含むものを含む)を使用して、 Alt+T (または、 Ctrl+W、1つ後ろに移動 Alt+B、など)。

見る

_info zsh select-Word-style
_

詳細については(zshのドキュメントがシステムにインストールされていると仮定します(Debianおよび派生物の_zsh-doc_パッケージ))。

カーソルがファイル名または中間の単語などにあるときに_transpose-words_がどのように動作するかを指定できるように特別に記述されているように見えるセクションが見つかります。

以下に、Wordコンテキストスタイルを使用してコンテキストを拡張する例をいくつか示します。

_   zstyle ':zle:*' Word-context \
          "*/*" filename "[[:space:]]" whitespace
   zstyle ':zle:transpose-words:whitespace' Word-style Shell
   zstyle ':zle:transpose-words:filename' Word-style normal
   zstyle ':zle:transpose-words:filename' Word-chars ''
_

これにより、カーソルが単語間の空白またはファイル名、ここでは/を含む単語にあるかどうかに応じて、転置単語を使用する2つの異なる方法が提供されます。空白では、標準のシェルルールで定義された完全な引数が置き換えられます。ファイル名では、英数字のみが転置されます。その他の場合、単語は_:zle:transpose-words_のデフォルトスタイルを使用して転置されます。

たとえば、次のようにします。

_autoload -U select-Word-style
zle -N select-Word-style
bindkey '\ez' select-Word-style
select-Word-style normal
zstyle :zle:transpose-words Word-style Shell
_

_transpose-words_は常にShellワードで機能しますが、他のすべてのWordウィジェットはnormalWordの定義を使用しますが、引き続き使用できます Alt+Z 変更する(_transpose-words_以外のウィジェットの場合)。

11

Zshのvimモードは、以前に認識したよりも少し進んでいることに気付きました。引数に対応するaテキストオブジェクトがあります。したがって、次のようなシーケンスを入力することで、筋肉の記憶を活用することができます EscdaaBPiSpace。しかし、8つのキーストロークが理想的とはほど遠いこともわかります。この操作では、Vimでエレガントにプラグインを実行する必要があるため、zshラインエディターの場合も同じです。

さらに、zshをvimモードにすると、すでに持っているバインディングが壊れますが、複製は簡単です。シェルにvimバインディングがあると本当にいいこともあります。しかし、私はまだ、挿入モードになっているシェルに対処する必要があることは問題に値しないというスタンスに傾いています。

3
Steven Lu

私は何度も同様の問題に直面しましたが、利用可能なクリーンなソリューションがあるとは思いません。あなたはこれを成し遂げるためにいくつかのハッカーを行うことができるはずです。最もハッカー的なアプローチは、おそらくコマンドの前にechoを付けて!:0を破棄することにより、コマンドを実行せずに単に履歴にダンプすることです。その後、上記のソリューションが機能します。

より良いアプローチは、ZSHのバージョンのreadline(正しく覚えていればzle)にフックすることです。これは通常のreadlineよりもはるかに強力であり、履歴に悪いコマンドを書き込むことなく、適切に操作できます。開始点として自動的にインラインを拡張する既存のプラグインを検討することをお勧めします。良い例がこのプラグインです: https://github.com/wazum/zsh-directory-dot-expansion (入力すると...../..に展開します)。実際、そのリポジトリを見ると、おそらく、作成者の元のスクリプトから1〜2行を変更することで、このロジックのプラグインを取得できるでしょう。

ユーザーが入力するときにzleを自動拡張するのではなく、いくつかのユーザーキーシーケンスに反応することに注意してください(言及したalt+Tコンボに似ています)。したがって、プラグインは単純な自動拡張よりもタブ補完に似ています。

2

Bashでは、 Ctrl-XCtrl-E 現在入力されているコマンドラインを$EDITORで開きます。必要に応じて編集し、保存して終了して実行します。

たとえば、デフォルトのエディターがVimの場合、<C-x><C-e>f dE$p:wqは初期コマンドラインを目的のコマンドラインに変換して実行します。もちろん、sideways.vimのようなプラグインがあれば、それも使用できます。

これは、引数をすばやく並べ替えるよりも一般的な機能であるため、多くの変換に役立ちます。空白のコマンドラインから開始するときにもこのモードに入ることができることに注意してください。

エディターでこの操作をキャンセルする場合は、ゼロ以外のステータスコード(Vim::cq)でエディターを終了するか、コマンドを空の文字列に置き換えて保存して終了します。

この操作の技術名はedit-and-execute-commandです。 .inputrcでキーの組み合わせを再バインドするか、man bashで詳細を確認できます。

あなたはZshについて尋ねました。 同様の機能が利用可能 のように見え、特定のZsh構成フレームワークではデフォルトで有効になっている場合があります。

1
wchargin

パスについて言及する特定のケースを解決するには、複雑な「切り替え順序」を使用する必要はありません。fzfのような最近のパス履歴管理からファジー検索履歴までが必要です。 Zshアーチウィキでdirsについて言及する必要があります。チェックする必要があります。

私はパスにcdし、現在パスから外れているそのパス内の何かに対していくつかのアクションを実行する必要があることがよくあります。パス履歴管理は、fzfと同様に効果を押し上げます。

0
Tuyen Pham