対話的に、bashで数字のn回の繰り返しを入力する方法


20

コマンドを実行したい

foo --bar=baz <16 zeroes>

16個のゼロを効率的に入力するには* Alt押した1 6 0ままにすると、次のことが160回繰り返されますが、これは望んでいないことです。emacsではAlt-[number]またはを使用できますCtrl-u 1 6 Ctrl-u 0が、bash Ctrl-uでは現在入力されている行を削除し、次のゼロは行に0を追加するだけです。

私が行った場合

foo --bar=baz $(printf '0%.0s' {1..16})

その後history、上記ではなく、正確に表示されfoo --bar=baz 0000000000000000ます。すなわち、bashは私が望むように動作しません。(編集:ポイントされている、$(...)コマンド置換を使用せずにいくつかのゼロを入力したい)

(*)「効率的に」の技術的定義は「with O(log n)keystrokes」、できれば16の桁数(16のすべての値)に等しい定数のキーストローク数であると思います。emacsの例は、この定義により効率的と見なされます。


1
どういうわけかbashにしたいようですknow what you want to do。複雑なネストされたコマンドでは、コマンド自体ではなく、履歴で実行結果を確認したい部分をbashがどのように知るのでしょうか?変数はどうですか?要するに、bashは常にcodeコードを実行した結果ではなく、履歴に記録されます。
不信者

@meuh、Altそれ自体は文字を送信しないので、altを押したり放したりしても、影響はありませんbash
ステファンシャゼラス

1
何をすべきかI平均@Unbeliever、それは大丈夫

@Unbeliever:私の編集を参照してください-段落のポイントは、historyコマンド置換を使用せずに数字を入力したいということでした。
ジョナスケルカー

自動的に入力されるようにするには、AutoKeyを使用すると便利です。これを使用して、フレーズの置換を作成したり、トリガーフレーズを入力したり、ホットキーを押したときに好きなことをほぼ実行できるPythonマクロを完成させることができます。GUIデスクトップ環境を必要とし、残りの回答は必要ないため、これを回答として含めませんでした。したがって、より一般的に適用できます。
ジョー

回答:


25

試して

エコーAlt+1Alt+6Ctrl+V0

これらの16個のゼロを挿入するAltための6回のキーストローク(少なくともUS / UK QWERTYキーボードを想定)です(1と6の両方を保持できます)。

標準viモード(set -o vi)を使用して、次のように入力することもできます。

エコー0 Escx16p

(6キーストロークも)。

emacs同等のモードとそれが単一のキャラクタ()以上を繰り返すのに使用できましたが、では動作しません。echo 0Ctrl+WAlt+1Alt+6Ctrl+Yzshbash

これらはすべてzsh(およびそれtcshがどこから来たのか)機能します。ではzsh、パディング変数展開フラグを使用して、次のように展開することもできますTab

echo $ {(l:16 :: 0 :)}Tab

(明らかにもっと多くのキーストローク)。

ではbash、あなたも持つことができbash、あなたを広げ$(printf '0%.0s' {1..16})Ctrl+Alt+E。ただし、行のすべて(ただし、グロブではない)を展開することに注意してください。

キーストロークの最小数のゲームをプレイするには、いくつかのキーに展開そのウィジェット結合することができる<some-number>XまでX繰り返し<some-number>回。そして、持っている<some-number>としても、それをさらに減らすためにベース36に。

zsh(と結合しましたF8):

repeat-string() {
  REPLY=
  repeat $1 REPLY+=$2
}
expand-repeat() {
  emulate -L zsh
  set -o rematchpcre
  local match mbegin mend MATCH MBEGIN MEND REPLY
  if [[ $LBUFFER =~ '^(.*?)([[:alnum:]]+)(.)$' ]]; then
    repeat-string $((36#$match[2])) $match[3]
    LBUFFER=$match[1]$REPLY
  else
    return 1
  fi
}
zle -N expand-repeat
bindkey "$terminfo[kf8]" expand-repeat

次に、16個のゼロの場合、次のように入力します。

エコーg0F8

(3回のキーストローク)ここg16、ベース36にあります。

これで、これらの16個のゼロを挿入する1つのキーにさらに減らすことができますが、それは不正行為になります。任意のウィジェットを定義できる場合、F22 0s(または$STRINGデフォルトで2、0)、F33 0s、F1F616 0s ...最大19 ...にバインドできます。

0キーを押したままにすると、1回のキーストロークで必要なだけゼロを挿入できます。


viその他に複数のバリエーションを提供していただきありがとうございます!
マークスチュワート

9

ターミナルエミュレータがキーストロークを食べない(たとえば、タブを切り替える)ことを前提としていますAlt-1 6 Ctrl-V 0。通常のxtermは動作します。control-Vは、数字と繰り返し文字を分割するために必要です(文字を繰り返していた場合、必要ありません)。

(これはとして知られるreadline機能digit-argumentであるためbind、関連する修飾キーの変更に使用できるはずです)


1
私のような人がこれらの質問につまずくときに便利な機能の名前を含めていただきありがとうございます。もう少し読むための関連リンク:SO質問およびbashマニュアル
16年

4

Emacsでは、通常C-q、数字入力から接頭引数を分離するために使用します。

Bashは、XON / XOFFフロー制御の問題を回避するためCtrl+vC-q、の代わりに使用します。

だから、使用できますAlt+1 Alt+6 Ctrl+v 0


3

もう1つのオプションは、4つのゼロを入力し、マウスを使用してさらに3回それをコピーして貼り付けることです。ダブルクリックして選択し、中ボタンで3回クリックして貼り付けます。


または、ゼロを1つ入力してそれをゴルフ/チートし、それを選択して貼り付けて2を取得します。それを選択して貼り付けて4を取得します。8を選択して貼り付け、16に再度貼り付けます。それはPOWerfulです:)
ジェフシャラー

ええ、しかし、4つのゼロを入力して繰り返し貼り付けることは、私にとって最適な努力と見返りのレベルです。余分なコピーと貼り付けはすべて作業のように思えます。
cas

3

マクロで遊ぶ:

ファンクションキーF8をバインドして、最後の単語を 2つ乗算します(前のスペースを上にします)(F8キーコードを使用して見つけましたCtrl-V F8):

$ bind '"\e[19~": "\C-w\C-y\C-y"'

に同じテキストを送信することで永続化できます ~/.inputrc

$ echo '"\e[19~": "\C-w\C-y\C-y"' >> ~/.inputrc

次に入力:

エコー0F8F8F8F8

ゼロの2 ^ 4倍を取得します。(まだ5回のキーストローク)。

またはタイプ:

エコーブックF8F8F8

2 ^ 3本の単語を取得します。

さらに高速:

4を掛けます:

$ bind '"\e[19~": "\C-w\C-y\C-y\C-w\C-y\C-y"'

エコー0F8F8

3キーを押します。

8倍(ファンクションキーと同じ数)

$ bind '"\e[19~": "\C-w\C-y\C-y\C-w\C-y\C-y\C-w\C-y\C-y"'

エコー00F8

まだ3回押します。

チート?

16を掛けてチートします。

$ bind '"\e[19~": "\C-w\C-y\C-y\C-w\C-y\C-y\C-w\C-y\C-y\C-w\C-y\C-y"'

エコー0F8

キーを2回押すだけです。(そしてまだ便利なシンプルな機能)

^^^^^^^^^^^^^^^^(ベース36?ハハ!):-P

明白に不正行為:

$ bind '"\e[19~": "0000000000000000"'

エコー F8

たった1(はい:1)のキーストローク。



のバインディングの変更ctrl+U

これを送る~/.inputrc

echo '"\C-u": universal-argument >> ~/.inputrc

~/.inputrcファイルを再読み取りします。

ctrl+Xctrl+R

emacsで通常行われているように(必要に応じて):

foo --bar = baz ctrl+U16 ctrl+U0

7つのキー(「セットアップ」の後)。

少し短い:

「universal-argument」のデフォルトの「multiply by 4」を使用し、次で終わる

 ctrl+V 0 

foo --bar = baz ctrl+Uctrl+Uctrl+V0

5つのキーのみ。

alt+n(arg:n)へのアクセスを使用する

foo --bar = baz Alt+16Ctrl+V0

16個のゼロを取得するための6つのキーです。

キーボードショートカットを変更しない:

あなたのバッシュにあなたが持っている場合bash C-u kills the currently-being-typed line
"\C-u":バインドされてunix-line-discardいるためです。

しかし、それはまた役立つかもしれません:
カーソルが消去される前に、それが「キルリング」に置かれるとき。

だからctrl+u消去し、消去されたctrl+yものを引き戻します。
きれいな行で:00eraseと入力し、2回ヤンクして元に戻し0000ます。
繰り返して00000000(8個のゼロ)を取得し、最後にコマンドを入力して2回ヤンクします。

最初のセット(7つのキーをctrl押し続けます):

00 ctrl+Uctrl+Yctrl+Y ctrl+U 

2番目のセット(5キー)

ctrl+Uctrl+Yctrl+Y ctrl+U 

これにより、消去リングに8つのゼロが追加され、必要なものを入力します。

 foo --bar = baz ctrl-Y ctrl-Y 

取得するため:

foo --bar=baz 0000000000000000

アイデアを得た後、必要なものを入力し、行の先頭(ctrl-Y)に移動し、上記のように(最大8つのゼロ)末尾に移動(ctrl-E)し、2回ヤンクします。

foo --bar = baz ctrl-A00ctrl-Uctrl-Yctrl-Y ctrl-Uctrl-Yctrl-Y ctrl-U ctrl-Ectrl-Yctrl-Y

これは15個のキーです(コマンド自体の横)。
短くはありませんが、それは利用可能なものでのみ機能しています。

これは少し短いです:

0000 ctrl-U ctrl-Y ctrl-Y ctrl-Y ctrl-Yctrl-A foo --bar = baz

11個のキーです


私の答えの編集を参照してください;-)
ステファンシャゼル

@StéphaneChazelasマクロを使用していますか?ベース36?zshでのみ?さあ...私の編集を参照してください:-P
sorontar

ええ、ベース36は頬に少し舌がありました。あなたF<n>の最後の言葉を複製するのが好き<n>です。
ステファンシャゼラス

すべての端末がF8で同じシーケンスを送信するわけではないことに注意してください(ただし、GNU / Linuxシステムで見られるほとんどの端末はsendを実行します^[[19~)。"$(tput kf8)"terminfoデータベース(またはの$terminfoハッシュzsh)から情報を取得するために参照してください。
ステファンシャゼラス

@StéphaneChazelasはい、そうです。または単に使用するctrl-v F8
-sorontar

2

casの答えのバリエーションとして、タイプ

printf '0%.s' {1..16}Enter
次に、マウスを使用してコピーして貼り付けます(1回)。おそらく、これはO(log n)ですが、(len(str(n))+ 20)であるため、効率が悪いと考えるかもしれません。しかし、注意してください:

  • 私のシステムで%.sは、1つのキャラクターを剃ることができました%.0s
  • 0000000000000000引数として複数のコマンドを実行する場合、これを行う必要があるのは1回だけです。

アウトグレンのジャックマンポイントその (printf "%0*d\n" number 0は、形式のアスタリスクが引数からフィールド幅を取得するように指示するため、は正の整数である)数値ゼロのストリング(および改行)をprintfます。具体的にprintf "%0*d" 16 0は、16個のゼロを出力します。しかし、これはのみ を処理する特殊なケースです0。  printf "%0*d" 16 12345印刷され0000000000012345、そしてprintf "%0*d" 16 foo印刷され0000000000000000 、エラーメッセージ。対照的に、この回答の他のコマンドは、123451234512345…orのような文字列を生成しますfoofoofoo… (およびについては以下を参照7%7%7%...)。

これを頻繁に行う場合は、シェル関数を定義することで効率化できます。

rep() { printf -- "$1%.0s" $(seq 1 "$2"); printf "\n"; }

ノート:

  • つかいます $(seq 1 "$2")代わりに(1.."$2"}見る-後者の意志ではない仕事があるため、このこのこの、およびこれを。これらの質問に対する回答の中にはの使用をeval推奨するものもありますが、これは一般的に推奨されません。
  • 書式文字列($1%.0s)はパラメーター($1)を含むため、(単一引用符ではなく)二重引用符で囲む必要があります。
  • --保護するためである$1で始まる値-
  • "%.0s$1"代わりにを使用して、同様の保護を取得できます"$1%.0s"
  • いずれにせよ、$1含む値%はそれを窒息させます。
  • 処理できるようにする必要がある場合 $1を含む値を%

    rep() { local i; for ((i=0; i<$2; i++)); do printf '%s' "$1"; done; printf "\n"; }

また、このような関数を定義したら、次のようなことができます

foo --bar=baz "$(rep 0 16)"

これはのタイピングよりわずかに少ないです"$(printf '0%.0s' {1..16})"


または、printf "%0*d" 16 016個のゼロを印刷します。形式でのアスタリスクは、引数からフィールド幅がかかります
グレンはジャックマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.