Basamakta bir basamağın n tekrarını nasıl etkileşimli olarak girerim


20

Komutu çalıştırmak istiyorum

foo --bar=baz <16 zeroes>

16 sıfırı nasıl verimli bir şekilde yazarım *? Basılır Altve 1 6 0basarsam, bir sonraki şeyi 160 kez tekrarlar, bu da istediğim şey değil. Emacs Alt-[number]veya ben kullanabilirsiniz Ctrl-u 1 6 Ctrl-u 0, ama bash Ctrl-uşu anda yazılan çizgi öldürür ve sonraki sıfır sadece 0 satır ekler.

Eğer yaparsam

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

Sonra historytam olarak yukarıdakileri gösterir, değil foo --bar=baz 0000000000000000; yani bash istediğim gibi davranmıyor. ( Düzenleme : nokta olmak, $(...)komut ikamesi kullanmadan sıfır sayısı girmek istiyorum )

(*) "Verimli bir şekilde" teknik tanımının "O (log n) tuş vuruşlarıyla", tercihen 16'daki basamak sayısına (16'nın tüm değerleri için) ve belki de bir sabite eşit sayıda tuş vuruşuna eşit olduğunu; emacs örneği bu tanım gereği verimli olur.


1
Bash'ın bir şekilde olmasını istiyor gibisin know what you want to do. Karmaşık bir iç içe komutta, bash, komutun kendisinin aksine tarihte yürütmenin sonucunu görmek istediğiniz parçaları nasıl bilebilirdi? Değişkenler ne olacak? Kısacası bash codekodun yürütülmesi sonucu değil , her zaman geçmişte olacaktır.
İnanılmaz

@meuh, Altkendi başına herhangi bir karakter göndermez, bu nedenle alt tuşuna basıp bırakmanın bash, ilgili olduğu kadar etkili olmaz .
Stéphane Chazelas

1
@Unbeliever Ne demek istediğimi yap ve sorun olmayacak
cat

@Unbeliever: benim düzenlememi görün — paragrafın bununla ilgisi olan nokta, historykomut ikamesi kullanmadan rakam girmek istiyorum.
Jonas Kölker

İşlerin sizin için otomatik olarak yazılmasını istediğinizde, AutoKey kullanmak için harika bir yardımcı programdır. Bununla birlikte, bir tetikleyici ifade yazıldığında veya bir kısayol tuşuna basıldığında istediğiniz her şeyi yapacak olan ifade ikameleri oluşturabilir veya Python makrolarını tamamlayabilirsiniz. Bunu bir cevap olarak eklemedim çünkü bir GUI masaüstü ortamı gerektiriyor ve cevapların geri kalanı yok - ve bu yüzden daha genel olarak uygulanabilir.
Joe

Yanıtlar:


25

Deneyin

yankı Alt+1Alt+6Ctrl+V0

Bu 16 sıfır eklemeyi ( Althem 1 hem de 6 için tutabilirsiniz) eklemek için 6 tuş vuruşu (en az US / UK QWERTY klavyeyi varsayarak ).

Ayrıca standart vimodu ( set -o vi) kullanabilir ve şunu yazabilirsiniz:

yankı 0 Escx16p

(ayrıca 6 tuş vuruşu).

emacsMod eşdeğer ve bu tek bir karakter daha tekrarlamak için kullanılabilir ( ) çalışır , ancak içinde .echo 0Ctrl+WAlt+1Alt+6Ctrl+Yzshbash

Bütün bunlar aynı zamanda zsh(ve tcshnereden geldiğinden) çalışacaktır . İle zsh, değişken genişleme bayraklarını doldurup aşağıdakileri kullanarak genişletebilirsiniz Tab:

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

(Açıkçası çok daha fazla tuş vuruşu).

İle bash, aynı zamanda olabilir bashŞu Verilerinizi genişletmek $(printf '0%.0s' {1..16})ile Ctrl+Alt+E. Gerçi, hatta her şeyi (globs değil) genişleteceğini unutmayın.

Anahtar vuruş az sayıda oyun oynamak için bazı anahtar genişletir o bir widget bağlamak olabilir <some-number>Xiçin Xtekrarlanan <some-number>zamanlarda. Ve <some-number>daha da azaltmak için taban 36'da.

İle zsh(bağlı 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

Ardından, 16 sıfır için şunları yazabilirsiniz:

yankı g0F8

(3 tuş vuruşlarını) burada gbir 16taban 36.

Şimdi, bunu 16 sıfır ekleyen bir tuşa indirgeyebiliriz, ancak bu hile olur. Biz bağlamak olabilir F2iki 0ler (veya iki $STRINGvarsayılan olarak, 0), F33 0, s F1F616 0sen keyfi widget'lar tanımlayabilirsiniz zaman 19 s ... yukarı ... olasılıklar sonsuzdur.

Belki de tuşunu basılı tutarsanız, 0sadece bir tuşa basarak istediğiniz kadar sıfır ekleyebilirsiniz :-)


viVe diğerleri için birden fazla varyasyon sağladığınız için teşekkürler !
Mark Stewart

9

Terminal öykünücünüzün tuş vuruşu yemediğini varsayalım (örneğin, sekmeleri değiştirmek için) - xterm'in çalıştığını söyleyin - tuşuna basabilirsiniz Alt-1 6 Ctrl-V 0. Tekrarlamak için sayı ve karakteri ayırmak için orada kontrol-V gereklidir (bir harfi tekrarlıyorsanız, buna ihtiyacınız olmazdı).

(Bu, bilinen bir okuma satırı özelliğidir digit-argument, bu nedenle bindilgili değiştirici anahtarları değiştirmek için kullanabilmeniz gerekir )


1
Teşekkür ederim, bu özelliğin adı da dahil olmak üzere, benim gibi insanlar bu soruları tökezlediğinde yararlıdır. Biraz daha okumak için ilgili bağlantılar: SO Question and bash manual
admalledd

4

Emacs, normalde C-qönek bağımsız değişkenini basamak girişinden ayırmak için kullanırdım .

Bash kullanır Ctrl+vyerine C-qXON / XOFF akış kontrolü ile sorunları önlemek için,.

Böylece kullanabilirsiniz Alt+1 Alt+6 Ctrl+v 0.


3

başka bir seçenek, dört sıfır yazmak ve daha sonra üç kez daha kopyalayıp yapıştırmak için fareyi kullanmaktır. seçmek için çift tıklayın, yapıştırmak için x 3 orta tıklayın.


Veya bir sıfır yazarak golf / biraz daha hile , 2 almak için seçin ve yapıştırın; seçmek için bunu seç & yapıştır 4; seçin ve 8'e tekrar yapıştırın ve 16 için tekrarlayın. Bu POWerful :)
Jeff Schaller

evet, ama 4 sıfır yazmak ve bunları tekrar yapıştırmak bana göre en iyi çaba seviyesine benziyor. tüm bu ekstra kopyalama ve yapıştırma işleri gibi görünüyor.
cas

3

Makrolarla oynamak:

F8Son sözcüğü (önceki boşluk kadar) iki ile çarpmak için işlev tuşunu bağlayın (kullanarak F8 tuş kodu bulunur Ctrl-V F8):

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

Bu aynı metni göndererek kalıcı hale getirilebilir ~/.inputrc

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

sonra şunu yazın:

yankı 0F8F8F8F8

sıfırın 2 ^ 4 katı olsun. (yine de 5 tuş vuruşu).

veya yazın:

yankı kitabıF8F8F8

2 ^ 3 kitap kelimesi almak için.

Hala daha hızlı:

4 ile çarpın:

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

yankı 0F8F8

3 tuşa basın.

8 ile çarpın (işlev tuşuyla aynı sayı)

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

yankı 00F8

Hala 3 tuşa basın.

Hile?

16 ile çarparak hile yapın.

$ 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"'

yankı 0F8

Sadece 2 tuşa basın. (ve yine de kullanışlı bir basit işlev)

^^^^^^^^^^^^^^^^^ (baz 36? Hah!) :-P

Açıkça hile:

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

Eko F8

Sadece 1 (evet: bir ) tuş vuruşu.



Bağlamanın değiştirilmesi ctrl+U:

Bunu şu adrese gönder ~/.inputrc:

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

~/.inputrcDosyayı tekrar okuyun :

ctrl+Xctrl+R

emacs'ta her zamanki gibi yapın (istediğiniz gibi):

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

7 tuş ("kurulumdan sonra").

Biraz daha kısa:

"Universal-argüman" ın varsayılan "4 ile çarp" işlevini kullanın ve

 ctrl+V 0 

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

Sadece 5 anahtar.

alt+n(Arg: n) erişimini kullanma

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

Bu 16 sıfır elde etmek için 6 anahtar.

Klavye kısayolunu değiştirmeme:

Eğer bashınızda varsa bash C-u kills the currently-being-typed line.
Çünkü "\C-u":bağlı unix-line-discard.

Ancak bu da yardımcı olabilir:
İmlecin silinmesinden önceki zaman, "öldürme halkasına" yerleştirilir.

Böylece silinenleri ctrl+usiler ve ctrl+ygeri çeker.
Temiz bir satırda: 00erase yazın ve yapmak için iki kez geri çekin 0000. (8 sıfır)
almak için işlemi tekrarlayın 00000000, son olarak komutu yazın ve iki kez geri çekin.

İlk set (7 tuş ctrlbasılı tutulur):

00 ctrl+Uctrl+Yctrl+Y ctrl+U 

İkinci set (5 tuş)

ctrl+Uctrl+Yctrl+Y ctrl+U 

Silme halkasında sekiz sıfır elde edersiniz, ardından ne istediğinizi yazın:

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

almak:

foo --bar=baz 0000000000000000

Fikri aldıktan sonra, ihtiyacınız olan şeyi yazabilir, satırın başına ( ctrl-Y), yukarıdaki gibi (sekiz adede kadar sıfır) sonuna kadar ( ctrl-E) gidebilir ve iki kez çekebilirsiniz.

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

Bu 15 tuş (komutun yanında).
Kısa değil, biliyorum, ama bu sadece mevcut olanla çalışıyor.

Bu biraz daha kısa:

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

11 anahtar


Cevabımın düzenlemesine bakın ;-)
Stéphane Chazelas

@ StéphaneChazelas Makrolar mı kullanıyorsunuz? Baz 36? Sadece zsh? Hadi ... benim düzenlememi gör :-P
sorontar

Eh evet, base36 yanakta biraz dildi. F<n>Son kelime <n>zamanlarını kopyalamanı seviyorum .
Stéphane Chazelas

Tüm terminallerin F8 üzerinde aynı diziyi göndermediğini unutmayın (GNU / Linux sistemlerinde bulunanların çoğu gönderir ^[[19~). "$(tput kf8)"Terminfo veritabanından (veya $terminfokarma girişinden) bilgi almak için bakınız zsh.
Stéphane Chazelas

@ StéphaneChazelas Evet, doğru. Veya sadece kullanınctrl-v F8
sorontar

2

Cas cevabının bir varyasyonu olarak , yazın

printf '% 0 .s' {1..16}Enter
ve daha sonra kopyalamak ve yapıştırmak için fareyi kullanın (bir kez). Tartışmalı olarak, bu O (log n), ancak (len (str (n)) + 20) olduğu için, verimsiz olduğunu düşünebilirsiniz. Ancak dikkat:

  • Bir karakteri tıraş edebildim - sistemimde, %.s gibi davranıyor gibiyim %.0s.
  • Bağımsız 0000000000000000değişken olarak ile birden fazla komut çalıştırmak istiyorsanız , bunu yalnızca bir kez yapmanız gerekir.

dışarı Glenn Jackman noktaları o (burada sayı pozitif bir tam sayıdır) dizesi yazdırır sayı sıfır (ve bir satır), biçiminde yıldız anlatır gibi tartışmalardan alan genişliğini almaya. Özellikle, 16 sıfır basacaktır. Ancak bu sadece ele alan özel bir durumdur .  yazdırılacak , yazdırılacak ve bir hata mesajı görüntülenecektir. Buna karşılık, bu yanıttaki diğer komutlar veya gibi dizeler üretecektir (ve aşağıya bakınız ).printf "%0*d\n" number 0printfprintf "%0*d" 16 0 0printf "%0*d" 16 123450000000000012345printf "%0*d" 16 foo0000000000000000123451234512345…foofoofoo…7%7%7%...

Bunu sık sık yapacaksanız, bir kabuk işlevi tanımlayarak akıcı hale getirebilirsiniz:

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

Notlar:

  • Kullanım $(seq 1 "$2")yerine (1.."$2"}bakın - İkinci irade değil iş çünkü bu , bu , bu ve bu . Bu soruların cevaplarının bazılarının kullanılmasını önerdiğini unutmayın eval, ancak bu genellikle önerilmez.
  • Bir dizge ( $1%.0s) içerdiğinden, biçim dizesi ( ) çift tırnak (tek tırnak yerine) olmalıdır $1.
  • --Karşı korumaktır $1ile başlayan değerler -.
  • Bunun "%.0s$1"yerine kullanarak benzer koruma elde edebilirsiniz "$1%.0s".
  • Her iki durumda da, $1içeren bir değer %, boğulmasına neden olur.
  • Aşağıdaki $1değerleri işleyebilmeniz gerekiyorsa %,

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

Ayrıca, böyle bir işlevi tanımladıktan sonra,

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

biraz daha az yazıyor "$(printf '0%.0s' {1..16})".


Alternatif olarak printf "%0*d" 16 016 sıfır basacaktır. Biçimdeki yıldız işareti, alan genişliğini bağımsız değişkenlerden alacaktır
glenn jackman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.