วิธีใช้อาร์กิวเมนต์จากคำสั่งก่อนหน้า


287

ฉันรู้ว่าEsc+ .ให้อาร์กิวเมนต์สุดท้ายของคำสั่งสุดท้ายแก่คุณ

แต่ฉันสนใจอาร์กิวเมนต์แรกของคำสั่งสุดท้าย มีกุญแจสำคัญในการทำเช่นนั้นหรือไม่?

ในบรรทัดเดียวกันมีวิธีทั่วไปในการรับอาร์กิวเมนต์ที่ n จากคำสั่งสุดท้ายหรือไม่ ฉันรู้ว่าในสคริปต์ทุบตีคุณสามารถใช้$0, $1ฯลฯ แต่เหล่านี้ไม่ทำงานบน commandline

นอกจากนี้สิ่งที่เกี่ยวกับการวนซ้ำผ่านอาร์กิวเมนต์ 0 ของคำสั่งก่อนหน้าเช่นเราสามารถทำกับอาร์กิวเมนต์สุดท้ายโดยการกดEsc+ อย่างต่อเนื่อง.?

คำตอบ:


284

เช่นเดียวกับM-.(meta-จุดหรือ ESC-จุดหรือ Alt-dot) เป็นฟังก์ชั่นที่ ReadLine yank-last-arg, M-C-y(meta-ควบคุม-Y หรือ ESC-Ctrl-Y หรือ Ctrl-Alt-y) yank-nth-argเป็นฟังก์ชั่นที่ โดยไม่ต้องระบุnมันจะแย้งอาร์กิวเมนต์แรกของคำสั่งก่อนหน้า

หากต้องการระบุอาร์กิวเมนต์ให้กด Escape แล้วกดตัวเลขหรือกดปุ่ม Alt ค้างไว้แล้วกดตัวเลข คุณสามารถทำได้Alt- -เพื่อเริ่มระบุจำนวนลบจากนั้นปล่อย Alt และกดตัวเลข (ซึ่งจะนับจากท้ายรายการอาร์กิวเมนต์

ตัวอย่าง:

ป้อนคำสั่งต่อไปนี้

$ echo a b c d e f g
a b c d e f g

ตอนนี้ที่พรอมต์ถัดไปพิมพ์echo(ด้วยช่องว่างต่อไปนี้) จากนั้น

กดAlt- Ctrl- yแล้วคุณจะเห็น:

$ echo a

โดยไม่ต้องกดEnterให้ทำดังต่อไปนี้

กดAlt- 3 Alt- Ctrl-y

กดAlt- - 2 Alt- Ctrl-y

ตอนนี้คุณจะเห็น:

$ echo ace

โดยวิธีการที่คุณสามารถใส่echoในบรรทัดโดยเลือกอาร์กิวเมนต์ 0:

กดAlt- 0 Alt- Ctrl-y

แก้ไข:

ในการตอบคำถามที่คุณเพิ่มไว้ในต้นฉบับ:

คุณสามารถกดAlt- 0จากนั้นกดซ้ำ ๆAlt- .เพื่อทำตามคำสั่งก่อนหน้า (หาเรื่อง 0) ในทำนองเดียวกันAlt- -จากนั้นทำซ้ำAlt- .จะช่วยให้คุณสามารถทะลุผ่านข้อโต้แย้งถัดไปจนถึงครั้งสุดท้าย

หากไม่มีข้อโต้แย้งที่เหมาะสมในบรรทัดหนึ่งในประวัติศาสตร์ระฆังจะดังขึ้น

หากมีชุดค่าผสมเฉพาะที่คุณใช้บ่อยคุณสามารถกำหนดแมโครเพื่อให้การกดแป้นหนึ่งครั้งจะทำงาน ตัวอย่างนี้จะเรียกอาร์กิวเมนต์ที่สองจากคำสั่งก่อนหน้านี้โดยการกด-Alt - คุณสามารถเลือกการกดแป้นพิมพ์ที่คุณต้องการแทนการกดแป้นนี้ คุณสามารถกดมันซ้ำ ๆ เพื่อก้าวผ่านสิ่งก่อนหน้าShiftY

หากต้องการลองป้อนแมโครที่พรอมต์ Bash:

bind '"\eY": "\e2\e."'

ในการทำให้ถาวรให้เพิ่มบรรทัดนี้ใน~/.inputrcไฟล์ของคุณ:

"\eY": "\e2\e."

น่าเสียดายที่นี่ไม่ได้ผลสำหรับ arg 0 หรือหมายเลขอาร์กิวเมนต์ลบ


14
เมื่อค้นหาแป้นพิมพ์ลัดสำหรับ bash / readline ฉันชอบเรียกใช้bind -lpและดูการผูกปัจจุบัน
Chad Skeeters

1
@ChadSkeeters: และ-s(ใหม่ในทุบตี 4) -xแมโครรายการสร้างขึ้นโดยใช้
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

โปรดทราบว่าคุณสามารถใช้อาร์กิวเมนต์หลักด้วยM-.เช่นกัน: Alt-3 Alt-Ctrl-yตัวอย่างเท่ากับการถือครองและการพิมพ์Alt 3.หากคุณพิมพ์3.หลาย ๆ ครั้งโดยไม่ปล่อยAltคุณต้องผ่านอาร์กิวเมนต์ที่สามของบรรทัดคำสั่งก่อนหน้า
ของหวาน

@ ขนมหวาน: ฉันพูดมากในวรรคสองของฉันแล้วแสดงตัวอย่าง
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

@ChadSkeeters ขอบคุณสำหรับคำเตือนว่าจะมีหลายร้อยรายการ! ฮ่า ๆ.
jdk1.0

309

!$ รับองค์ประกอบสุดท้ายของอาร์กิวเมนต์บรรทัดคำสั่งก่อนหน้า


115
!:3ทำให้คุณเป็นคนที่สาม
แมตต์ดอดจ์

108
! * ทำให้คุณทุกคนได้รับ
รางวัล

75
!!ทำให้คุณได้รับคำสั่งสุดท้ายทั้งหมด sudoประโยชน์ถ้าคุณลืมที่จะใช้
Un3qual

43
!:1-2ทำให้คุณได้รับ แต่ข้อโต้แย้ง 3 ข้อสุดท้าย
Tyler Brock

5
เพียงแค่คำเตือน - หากคุณใช้อาร์กิวเมนต์แบบรวมเช่นecho foo{,bar} bazกันคำสั่งจะถูกบันทึกตามที่พิมพ์และขยายหลังจากนั้น จากด้านบนให้ใช้echo !:1หลังจากแก้ปัญหาecho foo{,bar}แล้วขยายเป็นecho foo foobar
Sean

201

หากต้องการใช้อาร์กิวเมนต์แรกคุณสามารถใช้!^หรือ!:1

ตัวอย่าง:

$ echo a b c d e 
a b c d e
$ echo !^
echo a
a

$ echo a b c d e 
a b c d e
$ echo !:1
echo a
a

เนื่องจากคำถามของคุณเกี่ยวกับการใช้อาร์กิวเมนต์อื่น ๆ ต่อไปนี้เป็นประโยชน์บางประการ:

!^      first argument
!$      last argument
!*      all arguments
!:2     second argument

!:2-3   second to third arguments
!:2-$   second to last arguments
!:2*    second to last arguments
!:2-    second to next to last arguments

!:0     the command
!!      repeat the previous line

สี่รูปแบบแรกมีการใช้บ่อยกว่า แบบฟอร์ม!:2-ค่อนข้างโต้กลับเนื่องจากไม่มีอาร์กิวเมนต์ล่าสุด


มีวิธีรับไอเท็มที่สองหรือไม่? เช่นได้รับfile3จากmv file1 file2 file3 target/อะไร
Charlie Harding

3
ฉันชอบคำตอบนี้มากและเพื่อความสมบูรณ์ฉันขอแนะนำให้เพิ่มบรรทัดที่บอกเกี่ยวกับไวยากรณ์ '! -2' ที่ให้คุณเข้าถึงคำสั่งก่อนหน้านี้
bbv

1
@bbv ยิ่งไปกว่านั้นคำสั่ง '! 2' ที่สมบูรณ์ยิ่งขึ้นซึ่งช่วยให้คุณสามารถเข้าถึงรายการที่สองในประวัติศาสตร์ได้ (หากยังคงสามารถใช้ได้ขึ้นอยู่กับการตั้งค่าประวัติของคุณ) มีประโยชน์ถ้าคุณแสดงหมายเลขประวัติในแต่ละพรอมต์
816-8055

53

ฉันชอบ @larsmans ตอบมากฉันต้องเรียนรู้เพิ่มเติม การเพิ่มคำตอบนี้เพื่อช่วยผู้อื่นในการค้นหาส่วนหน้าคนและรู้ว่าต้องทำอะไรกับ google สำหรับ:

$ man  -P 'less -p ^HISTORY\ EXPANSION' bash
<...>
Word Designators

Word designators are used to select desired words from the event.
A : separates the event specification from the word designator.
It may be omitted if the word designator begins with a ^, $, *, -,
or %.  Words are numbered from the beginning of the line, with the
first word being denoted by 0 (zero).  Words are inserted into the
current line separated by single spaces.

   0 (zero)
          The zeroth word.  For the shell, this is the command word.
   n      The nth word.
   ^      The first argument.  That is, word 1.
   $      The last argument.
   %      The word matched by the most recent ‘?string?’ search.
   x-y    A range of words; ‘-y abbreviates 0-y’.
   *      All of the words but the zeroth.
          This is a synonym for 1-$’.  
          It is not an error to use * if there is just one word in
          the event; the empty string is returned in that case.
   x*     Abbreviates x-$.
   x-     Abbreviates x-$ like x*, but omits the last word.

   If a word designator is supplied without an event
   specification, the previous command is used as the event.

18

! ^ อาจเป็นคำสั่งสำหรับอาร์กิวเมนต์แรก ฉันไม่แน่ใจว่ามีวิธีที่จะได้รับ nth


7
มันเป็น!: n ตามที่แนะนำข้างต้น
Sergiu

มีวิธีรับไอเท็มสุดท้ายที่ n เช่น!:nนั้น แต่นับจากจุดสิ้นสุดแทนที่จะเป็นจุดเริ่มต้นหรือไม่
ชาร์ลีฮาร์ดิง

14

นอกจากนี้คุณยังสามารถรับข้อโต้แย้งจากคำสั่งใด ๆ ในประวัติศาสตร์ของคุณ!


$ echo a b c d e f g
a b c d e f g
$ echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar
$ history | tail -5
  601  echo build/libs/jenkins-utils-all-0.1.jar
  602  history | tail -10
  603  echo a b c d e f g
  604  echo build/libs/jenkins-utils-all-0.1.jar
  605  history | tail -5
$ echo !-3:4
echo d
d
$ echo !604:1
echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar


4

ทดสอบบน Ubuntu 18.04


วิธีแทรกอาร์กิวเมนต์ก่อนหน้า:

  • Alt+ .: แทรกอาร์กิวเมนต์ล่าสุดจากคำสั่งสุดท้าย
  • Alt+ #+ .: แทรกอาร์กิวเมนต์สุดท้าย #nth จากคำสั่งสุดท้าย
  • Alt+ -, #, Alt+ ., zsh: Alt + -+ #+ .: แทรก #nth อาร์กิวเมนต์แรกจากคำสั่งสุดท้าย

ใน Linux คุณสามารถทำซ้ำคำสั่งเพื่อย้อนกลับไปในประวัติศาสตร์

ตัวอย่าง:

คำสั่งสุดท้ายคือ:

mv foo bar
  • Alt+ 0+ .: แทรกอาร์กิวเมนต์แรกของคำสั่งสุดท้าย =mv
  • Alt+ 2+ .: แทรกอาร์กิวเมนต์ลำดับที่ 2 สุดท้ายของคำสั่งสุดท้าย =foo
  • up, Ctrl+ w: คำสั่งสุดท้ายที่ไม่มีคำสุดท้าย =mv foo

ทางลัดทั่วไป

  • Ctrl+ w: ลบคำสุดท้ายออกจากเคอร์เซอร์
  • Alt+ d: ลบคำถัดไปจากเคอร์เซอร์
  • Ctrl+ k: ตัดทุกอย่างหลังจากเคอร์เซอร์
  • Ctrl+ u, zsh: Alt + w: ตัดทุกอย่างก่อนเคอร์เซอร์
  • zsh: Ctrl + u: ตัดคำสั่งทั้งหมด(ใน bash คุณสามารถรวมCtrl+ u, Ctrl+ k)
  • Ctrl+ y: วางอักขระก่อนหน้านี้ตัดด้วยCtrl+ uและCtrl+k
  • Ctrl+ _: เลิกทำการแก้ไขล่าสุด(มีประโยชน์มากเมื่อเกินCtrl+ w)
  • Ctrl+ left: เลื่อนไปที่คำสุดท้าย
  • Ctrl+ right: เลื่อนไปที่คำถัดไป
  • homeหรือCtrl+ a: เลื่อนไปที่จุดเริ่มต้นของบรรทัด
  • endหรือCtrl+ e: เลื่อนไปที่ท้ายบรรทัด

เมื่อต้องการวนซ้ำอาร์กิวเมนต์ในคำสั่งก่อนหน้า

ใช้งานได้เฉพาะใน zsh

เรียกใช้หรือเพิ่มสิ่งนี้ใน ~/.zshrc

autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[:" copy-earlier-word

ตอนนี้ใช้Alt+ .เพื่อย้อนกลับตามที่คุณต้องการจากนั้นใช้Alt+ :เพื่อวนซ้ำอาร์กิวเมนต์

สมมติว่าคำสั่งสุดท้ายคือ

echo 1 2 3 4 5
  • Alt+ .:5
  • Alt+ .+ ::4
  • Alt+ .+ :+ ::3
  • Alt+ .+ :+ :+ ::2
  • Alt+ .+ :+ :+ :+ ::1
  • Alt+ .+ :+ :+ :+ :+ ::echo

แหล่งที่มา: https://stackoverflow.com/a/34861762/3163120

เพื่อดูทางลัดทั้งหมดที่มี

  • ทุบตี: bind -lp
  • zsh: bindkey -L

ฉันกำลังอัปเดตสิ่งนี้อยู่ในส่วนสำคัญนี้https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9


1
Alt .on Zsh บน Mac กำลังพิมพ์🤔
André Pena

1
เอส. ใช้งานได้แม้ว่าจะใช้งานได้กับไฟล์ล่าสุดเท่านั้น คุณไม่สามารถพิมพ์เพื่อย้อนเวลากลับไปได้ มันอาจจะคุ้มค่าที่จะอัพเดทคำตอบ ขอบคุณมาก.
André Pena

คุณสามารถเรียกใช้bindkey -Lในzshเพื่อดูทางลัดทั้งหมดที่ถูกผูกไว้มันอาจจะช่วยระบุปัญหาหรือแม้แต่หาคำสั่งที่มีประโยชน์อื่น ๆ ในกรณีของฉันเช่น: ผูกพันถูกกำหนดให้เป็น Alt . (ไปยังหน้าจอที่ชัดเจน) -> -> (เช่นเดียวกับการลบคำสุดท้าย)bindkey "^[." insert-last-wordCtrl Lbindkey "^L" clear-screenAlt+Ctrl hbindkey "^[^H" backward-kill-wordCtrl w
Madacol

@ Madacol ฉันยังสามารถเห็นปุ่มผูกคำที่คัดลอกมาก่อนหน้าคำที่กล่าวถึงเป็น bindkey "^[^_" copy-prev-word
kikeenrique

3

โดยทั่วไปจะมีการใช้งานใน yanking ก่อนหน้า (คำสั่ง) ข้อโต้แย้ง

ตัวอย่างเช่นหากใช้คำสั่งต่อไปนี้:

echo Hello, world how are you today?

จากนั้นHello,จะเป็นข้อโต้แย้งแรกและtoday?ข้อที่หกนั่นคือข้อโต้แย้งสุดท้าย ความหมายสามารถอ้างอิงได้โดยการพิมพ์:

Alt+6 ติดตามโดย Ctrl-Alt-6


Ctrlจะแสดงเป็นตัวละครแบบดั้งเดิมหมวก^ใช้ได้กับชื่อคีย์และAltเป็นM-ที่เป็นM etaคำนำหน้า

ดังนั้นทางลัดด้านบนสามารถนิยามได้ว่า^Myเป็นการงัด


นอกจากนี้ยังมีทางลัดการแทนที่หมวกในบรรทัดคำสั่ง:

echo Hello, world!

^Hello^Bye

Bye, world!

เพื่อแทนที่สตริงที่จับคู่แรกของคำสั่งก่อนหน้าความหมาย:

Hello, world! Hello, people!

^Hello^Bye

จะส่งผลให้:

Bye, world! Hello, people!

ออกจากการแข่งขันนัดที่สอง ( hello) ไม่เปลี่ยนแปลง

หมายเหตุ: อย่าเว้นช่องว่างระหว่างหมวกมิฉะนั้นการทำงานจะไม่ทำงาน


ด้านบนเป็นเพียงทางลัดสำหรับ:

!:s/Hello/Bye

การทดแทนระดับเหตุการณ์ (*) สำหรับสตริงที่พบ (จับคู่) ครั้งแรกในคำสั่งก่อนหน้าในขณะที่คำนำหน้าส่วนแรกด้วยgสวิตช์จะนำไปใช้กับทั้งบรรทัด g lobally :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

เป็นมักจะถูกดำเนินการในคำสั่งอื่น ๆ ที่เกี่ยวข้องเช่นsed, viและในregex(regular expression) - เป็นวิธีมาตรฐานในการค้นหา ( สตริงการแข่งขัน )

ไม่คุณไม่สามารถทำได้!:sg/Hello/Byeหรือ!:s/Hello/Bye/gนี่คือไวยากรณ์ !


  • ! สำหรับเหตุการณ์; เหตุการณ์อาจถูกเข้าใจว่าเป็นเอาต์พุตคำสั่งหรือการดำเนินการที่ทำในประวัติคำสั่ง

นั่นคือสิ่งที่ฉันเข้าใจโดยใช้มันเองและลองทำสิ่งต่าง ๆ ด้วยตัวเองจากสิ่งที่ฉันอ่านจากแหล่งต่าง ๆ รวมถึงหน้าคู่มือบล็อกและฟอรัม

หวังว่ามันจะส่องแสงออกไปในรูปแบบลึกลับของbashเชลล์ Bourne-Again (เล่นบนshเชลล์ซึ่งตัวเองเรียกว่าบอร์นเชลล์หลังจากนามสกุลของนักประดิษฐ์) สิ่งที่เป็นเชลล์เริ่มต้นในการกระจายจำนวนมากรวมถึงเซิร์ฟเวอร์ ( เซิร์ฟเวอร์ OS )


3

! ^ คุณจะได้รับสิ่งแรกที่คุณจะได้รับ! $ จะได้รับสิ่งสุดท้ายที่คุณจะได้รับ:! nจะได้รับสิ่งที่คุณต้องการ


0

วิธีที่อธิบายในตอนท้ายของคำตอบที่ยอมรับนั้นใช้ได้กับอาร์กิวเมนต์ zeroth สำหรับฉันด้วย ฉันมีบรรทัดเหล่านี้ใน~/.inputrc:

"\en": "\e0\e."
"\em": "\e1\e."
"\e,": "\e2\e."

\e2\e.มีข้อได้เปรียบมากกว่า\e2\e\C-yที่จะวนรอบคำสั่งก่อนหน้าหากกดซ้ำหลายครั้งแทนที่จะใส่อาร์กิวเมนต์ที่สองของคำสั่งก่อนหน้าหลายครั้ง

!!\e^การแทรกคำสั่งก่อนหน้านี้ทั้งคุณสามารถพิมพ์ เป็น\e^history-expand-line


0

หากคุณใช้ mac คุณจะมีแนวโน้มที่จะได้รับอักขระเพิ่มเติมด้วย ctrl + ตัวอักษร ฉันมีคีย์ตัวเลือกแถบพื้นที่ด้านขวาของฉันซึ่งกำหนดเป็นเมตาในเทอร์มินัลของฉัน (iTerm2) ตั้งค่า ซึ่งหมายความว่าฉันใช้ปุ่มเพื่อนำทางด้วยคำและดึงพารามิเตอร์จากคำสั่งก่อนหน้า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.