ฉันจะป้อน n ซ้ำของตัวเลขในทุบตีโต้ตอบได้อย่างไร


20

ฉันต้องการเรียกใช้คำสั่ง

foo --bar=baz <16 zeroes>

ฉันจะพิมพ์ 16 ศูนย์ได้อย่างมีประสิทธิภาพได้อย่างไร ถ้าฉันAltกดค้างไว้1 6 0มันจะทำซ้ำสิ่งต่อไป 160 ครั้งซึ่งไม่ใช่สิ่งที่ฉันต้องการ ใน emacs ฉันสามารถใช้Alt-[number]หรือCtrl-u 1 6 Ctrl-u 0แต่ในทุบตีCtrl-uฆ่าสายที่ถูกพิมพ์ในขณะนี้และศูนย์ต่อไปเพียงแค่เพิ่ม 0 ลงในบรรทัด

ถ้าฉันทำ

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

จากนั้นhistoryแสดงให้เห็นอย่างชัดเจนข้างต้นและไม่foo --bar=baz 0000000000000000; ie bash ไม่ทำงานในแบบที่ฉันต้องการ ( แก้ไข : เป็นจุดฉันต้องการที่จะใส่จำนวนศูนย์โดยไม่ต้องใช้การ$(...)ทดแทนคำสั่ง)

(*) ฉันเดาว่าคำจำกัดความทางเทคนิคของ "มีประสิทธิภาพ" คือ "กับการกดแป้นพิมพ์ O (log n)" โดยเฉพาะอย่างยิ่งการกดแป้นจำนวนหนึ่งเท่ากับจำนวนหลักใน 16 (สำหรับค่าทั้งหมด 16) บวกอาจคงที่ ตัวอย่าง emacs มีคุณสมบัติตามที่กำหนดไว้อย่างมีประสิทธิภาพ


1
know what you want to doเสียงเหมือนคุณต้องการทุบตีเพียงอย่างใด ในคำสั่งที่ซ้อนกันที่ซับซ้อนวิธีทุบตีจะรู้ว่าส่วนใดที่คุณต้องการที่จะเห็นผลของการดำเนินการในประวัติศาสตร์เมื่อเทียบกับคำสั่งตัวเอง? แล้วตัวแปรล่ะ ในทุบตีสั้นมักจะมีcodeในประวัติศาสตร์ไม่ได้ผลของการรันรหัส
ผู้ที่ไม่เชื่อ

@meuh, Altด้วยตัวเองไม่ได้ส่งตัวอักษรใด ๆ ดังนั้นการกดและปล่อย Alt จะไม่ได้มีผลกระทบใด ๆ เท่าที่bashเป็นห่วง
Stéphane Chazelas

1
@ Unbeliever ทำในสิ่งที่ฉันหมายถึงและมันก็จะโอเค
แมว

@ Unbeliever: ดูการแก้ไขของฉัน - จุดของย่อหน้าที่ต้องทำhistoryคือฉันต้องการใส่ตัวเลขโดยไม่ต้องใช้การแทนที่คำสั่ง
Jonas Kölker

เมื่อใดก็ตามที่คุณต้องการพิมพ์สิ่งต่าง ๆ โดยอัตโนมัติสำหรับคุณ AutoKey เป็นเครื่องมือที่ยอดเยี่ยมในการใช้งาน ด้วยคุณสามารถสร้างการแทนที่วลีหรือแมโคร Python ที่สมบูรณ์ที่จะทำเกือบทุกอย่างที่คุณต้องการเมื่อพิมพ์วลีทริกเกอร์หรือกดปุ่มลัด ฉันไม่ได้รวมสิ่งนี้เป็นคำตอบเพราะต้องใช้สภาพแวดล้อม GUI บนเดสก์ท็อปและส่วนที่เหลือของคำตอบไม่ได้ - และโดยทั่วไปจะใช้งานได้มากกว่า
โจ

คำตอบ:


25

ลอง

echo Alt+1Alt+6Ctrl+V0

นั่นคือการกดปุ่ม 6 ครั้ง (สมมติว่าเป็นคีย์บอร์ด US / UK QWERTY อย่างน้อย) เพื่อแทรก 16 ศูนย์เหล่านั้น (คุณสามารถถือได้Altทั้ง 1 และ 6)

คุณสามารถใช้viโหมดมาตรฐาน( set -o vi) และประเภท:

echo 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 ค่าคุณพิมพ์:

echo g0F8

(3 การกดแป้น) ที่gอยู่16ในฐาน 36

ตอนนี้เราสามารถลดให้เหลือหนึ่งคีย์ที่แทรกค่าศูนย์ 16 เหล่านั้นได้แม้ว่ามันจะเป็นการโกง เราสามารถผูกF2สอง0s (หรือสอง$STRING, 0 โดยค่าเริ่มต้น), F33 0s, F1F616 0s ... ถึง 19 ... ความเป็นไปได้ไม่มีที่สิ้นสุดเมื่อคุณสามารถกำหนดวิดเจ็ตโดยพลการ

บางทีฉันควรพูดถึงว่าถ้าคุณกดปุ่มค้างไว้0คุณสามารถแทรกเลขศูนย์ได้มากเท่าที่คุณต้องการด้วยการกดแป้นเดียว :-)


ขอบคุณที่ให้รูปแบบที่หลากหลายสำหรับviและอื่น ๆ !
Mark Stewart

9

ทะนงจำลอง terminal ของคุณไม่กินการกดแป้นพิมพ์ (เช่นแท็บสวิทช์) xterm -plain Alt-1 6 Ctrl-V 0ทำงานคุณสามารถกด จำเป็นต้องใช้ control-V ในการทำลายจำนวนและตัวอักษรเพื่อทำซ้ำ (ถ้าคุณทำจดหมายซ้ำคุณไม่ต้องการมัน)

(นี่คือคุณสมบัติ readline ที่รู้จักในชื่อdigit-argumentดังนั้นคุณควรจะสามารถใช้bindเพื่อเปลี่ยนคีย์ตัวแก้ไขที่เกี่ยวข้อง)


1
ขอบคุณรวมถึงชื่อของคุณสมบัตินี้มีประโยชน์เมื่อคนอย่างฉันสะดุดกับคำถามเหล่านี้ ลิงค์ที่เกี่ยวข้องสำหรับการอ่านเพิ่มเติม: SO Question and bash manual
admalledd

4

ใน Emacs ปกติแล้วฉันจะใช้C-qเพื่อแยกอาร์กิวเมนต์คำนำหน้าออกจากอินพุตหลัก

Bash ใช้Ctrl+vแทนC-qเพื่อหลีกเลี่ยงปัญหาการควบคุมการไหลของ XON / XOFF

Alt+1 Alt+6 Ctrl+v 0ดังนั้นคุณสามารถใช้


3

อีกตัวเลือกหนึ่งคือพิมพ์สี่ศูนย์แล้วใช้เมาส์เพื่อคัดลอกและวางสามครั้ง ดับเบิลคลิกเพื่อเลือกคลิกกลางที่ x 3 เพื่อวาง


หรือตีกอล์ฟ / โกงบางอย่างโดยพิมพ์หนึ่งศูนย์เลือก & วางเพื่อรับ 2; เลือก & วางเพื่อรับ 4; เลือก & วางถึง 8 และอีกครั้งสำหรับ 16. เป็น POWerful :)
Jeff Schaller

ใช่ แต่การพิมพ์ 4 ศูนย์และการวางซ้ำพวกเขาดูเหมือนระดับที่ดีที่สุดของความพยายามเทียบกับผลตอบแทนให้ฉัน ทั้งหมดที่คัดลอกและวางพิเศษดูเหมือนงาน
cas

3

เล่นกับมาโคร:

ผูกปุ่มฟังก์ชั่นF8เพื่อทวีคูณสองคำสุดท้าย(ขึ้นช่องว่างก่อนหน้า) (รหัสคีย์ F8 ที่พบโดยใช้Ctrl-V F8):

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

สามารถทำได้อย่างถาวรโดยส่งข้อความเดียวกันไปที่ ~/.inputrc

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

จากนั้นพิมพ์:

echo 0F8F8F8F8

เพื่อรับ 2 ^ 4 คูณศูนย์ (ยังกดแป้น 5 ครั้ง)

หรือพิมพ์:

echo bookF8F8F8

เพื่อรับ 2 ^ 3 คำในหนังสือ

ยังเร็วกว่า:

คูณด้วย 4:

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

echo 0F8F8

3 ปุ่มกด

คูณด้วย 8 (หมายเลขเดียวกับปุ่มฟังก์ชัน)

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

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

echo 0F8

กดปุ่มเพียง 2 ครั้ง (และยังเป็นฟังก์ชั่นง่าย ๆ ที่มีประโยชน์)

^^^^^^^^^^^^^^^ (ฐาน 36? Hah!) :-P

การโกงอย่างชัดเจน:

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

เสียงสะท้อน F8

กดแป้นเพียง 1 (ใช่: หนึ่ง )



การเปลี่ยนการโยงสำหรับctrl+U:

ส่งไปที่~/.inputrc:

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

อ่าน~/.inputrcไฟล์อีกครั้ง:

ctrl+Xctrl+R

ทำตามปกติใน emacs (ตามที่คุณต้องการ):

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

7 ปุ่ม (หลังจาก "การตั้งค่า")

สั้นลงเล็กน้อย:

ใช้ค่าเริ่มต้น "คูณด้วย 4" ของ "อาร์กิวเมนต์สากล" และลงท้ายด้วย

 ctrl+V 0 

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

เพียง 5 ปุ่มเท่านั้น

ใช้การalt+nเข้าถึง (หาเรื่อง: n)

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

นั่นคือ 6 ปุ่มเพื่อรับ 16 ศูนย์

ไม่เปลี่ยนแป้นพิมพ์ลัด:

bash C-u kills the currently-being-typed lineถ้าในการทุบตีของคุณคุณมี
นั่นเป็นเพราะเป็นไปผูก"\C-u":unix-line-discard

แต่นั่นอาจช่วยได้เช่นกัน:
เมื่อใดสิ่งที่ก่อนที่เคอร์เซอร์จะถูกลบมันจะถูกวางใน "kill-ring" ด้วย

ดังนั้นctrl+uลบและctrl+yดึงสิ่งที่ถูกลบออกไป
บนเส้นสะอาด: ประเภทลบมันและดึงเอามันกลับมาเป็นครั้งที่สองที่จะทำให้มัน00 ทำซ้ำเพื่อรับ(8 ศูนย์) สุดท้ายพิมพ์คำสั่งแล้วดึงกลับมาสองครั้ง0000
00000000

ชุดแรก (กดปุ่ม 7 ครั้งctrl):

00 ctrl+Uctrl+Yctrl+Y ctrl+U 

ชุดที่สอง (5 ปุ่ม)

ctrl+Uctrl+Yctrl+Y ctrl+U 

นั่นจะได้แปดศูนย์ในวงแหวนลบแล้วพิมพ์สิ่งที่คุณต้องการ:

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

ที่จะได้รับ:

foo --bar=baz 0000000000000000

หลังจากที่คุณได้รับแนวคิดคุณอาจพิมพ์สิ่งที่คุณต้องการไปที่จุดเริ่มต้นของบรรทัด ( ctrl-Y) ทำตามด้านบน (สูงสุดแปดศูนย์) ไปที่จุดสิ้นสุด ( ctrl-E) และงัดสองครั้ง

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éphane Chazelas

@ StéphaneChazelasใช้มาโครหรือไม่ ฐาน 36? เฉพาะใน zsh C'mon ... ดูการแก้ไขของฉัน :-P
sorontar

ใช่ฐาน 36 เป็นแก้มลิ้นเล็กน้อย ฉันชอบF<n>คำซ้ำซ้อนของคุณ<n>ครั้ง
Stéphane Chazelas

โปรดทราบว่าไม่ใช่เทอร์มินัลทั้งหมดส่งลำดับเดียวกันบน F8 (แม้ว่าส่วนใหญ่ที่พบในระบบ GNU / Linux จะส่ง^[[19~) ดู"$(tput kf8)"เพื่อรับข้อมูลจากฐานข้อมูล terminfo (หรือ$terminfoแฮชzsh)
Stéphane Chazelas

@ StéphaneChazelasใช่ถูกต้อง หรือเพียงใช้ctrl-v F8
sorontar

2

ในฐานะที่เป็นรูปแบบของคำตอบของ CASประเภท

printf '0% .s' {1..16}Enter
จากนั้นใช้เมาส์เพื่อคัดลอกและวาง (หนึ่งครั้ง) อาจเป็นไปได้ว่านี่คือ O (log n) แต่เนื่องจาก (len (str (n)) + 20) คุณอาจพิจารณาว่ามันไม่มีประสิทธิภาพ แต่หมายเหตุ:

  • ผมสามารถที่จะโกนตัวละครตัวหนึ่ง - ในระบบของฉันดูเหมือนว่าจะมีพฤติกรรมเช่นเดียวกับ%.s%.0s
  • หากคุณต้องการเรียกใช้หลายคำสั่งด้วย0000000000000000อาร์กิวเมนต์คุณจะต้องทำสิ่งนี้เพียงครั้งเดียว

เกล็นจุด Jackman ออกว่า (ที่จำนวนเป็นจำนวนเต็มบวก) จะพิมพ์สตริงของหมายเลขศูนย์ (และขึ้นบรรทัดใหม่) เช่นเครื่องหมายดอกจันในรูปแบบที่บอกจะใช้ความกว้างของเขตข้อมูลจากการขัดแย้ง โดยเฉพาะจะพิมพ์ 16 ศูนย์ แต่เป็นกรณีพิเศษที่จับนี้เท่านั้น  จะพิมพ์และจะพิมพ์ และข้อความแสดงข้อผิดพลาด ในทางตรงกันข้ามคำสั่งอื่น ๆ ในคำตอบนี้จะสร้างสตริงเช่นหรือ (และดูด้านล่างสำหรับ)printf "%0*d\n" number 0printfprintf "%0*d" 16 0 0printf "%0*d" 16 123450000000000012345printf "%0*d" 16 foo0000000000000000123451234512345…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 0จะพิมพ์ 16 ศูนย์ เครื่องหมายดอกจันในรูปแบบจะใช้ความกว้างของฟิลด์จากอาร์กิวเมนต์
เกล็นแจ็
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.