ค้นหาคำสั่งก่อนหน้าด้วยคำนำหน้าฉันเพิ่งพิมพ์


67

เราสามารถใช้ลูกศรขึ้นและลงเพื่อเลื่อนดูประวัติคำสั่ง

ใน IDEs บางตัวเช่น Matlab หากเราป้อนบางสิ่งแล้วกดปุ่มลูกศรเราจะเลื่อนเฉพาะคำสั่งประวัติที่เริ่มต้นด้วยสิ่งที่เรามีอินพุต สะดวกมาก แต่ในเชลล์เทอร์มินัลสิ่งนี้ไม่ทำงาน

มีวิธีรับฟังก์ชั่นที่คล้ายกันในเชลล์เทอร์มินัลไหม? และเคล็ดลับอื่น ๆ สำหรับการปรับปรุงประสิทธิภาพในการใช้เทอร์มินัล?


คุณสามารถใช้เชลล์ที่จัดเตรียมคุณลักษณะดังกล่าวได้เช่นfish)
yoann

@yoann คุณคิดว่าทุบตีไม่ได้ มันผ่าน readline เพียงไม่สามารถเข้าถึงได้โดยค่าเริ่มต้น
muru

@muru ฉันรู้ว่า CTRL + R เป็น bash และคำตอบของ egmont นั้นให้วิธีที่เป็นระเบียบในการทำ Page Up / Page Down มีวิธีทำอย่างไรกับปุ่มลูกศร?
yoann

1
@yoann ตรวจสอบunix.stackexchange.com/a/76591/70524 แทน\e[5~และ\e[6~, ใช้\e[A, \e[B.
muru

คำตอบ:


95

CtrlRสิ่งที่คุณกำลังมองหาอยู่

พิมพ์CtrlRแล้วพิมพ์ส่วนหนึ่งของคำสั่งที่คุณต้องการ Bash จะแสดงคำสั่งแรกที่ตรงกัน การพิมพ์ต่อเนื่องCtrlRและทุบตีจะวนไปตามคำสั่งก่อนหน้าที่ตรงกัน

หากต้องการค้นหาย้อนหลังในประวัติศาสตร์ให้พิมพ์CtrlSแทน (หากCtrlSไม่ได้ผลสำหรับคุณนั่นอาจหมายความว่าคุณต้องปิดการใช้งานการควบคุมการไหลของ XON / XOFF: เพื่อให้ทำงานstty -ixonได้)

นี้เป็นเอกสารภายใต้ "การค้นหา" man bashใน


1
Ctrl-Qเพื่อออกจากสถานะน้ำแข็งถ้าคุณกดแล้วCtrl-Sโดยไม่ต้องปิดการควบคุมการไหลก่อนและทำให้ขั้วของคุณถูกแช่แข็ง
HongboZhu

26

วางสิ่งเหล่านี้ในของคุณ~/.inputrc:

"\e[5~": history-search-backward
"\e[6~": history-search-forward

สิ่งเหล่านี้ผลิตPage UpและPage Downประพฤติตามที่คุณต้องการ (การกระจายบางคนมีมันแล้วกำหนดค่าสำหรับคุณ.) ผมเองหาวิธีเหล่านี้สะดวกสบายกว่าCtrl+ หรือRhistory


นี่เป็นวิธีที่สะดวกที่สุดในคำตอบปัจจุบันทั้งหมด คุณช่วยอธิบายกลไกการทำงานหน่อยได้ไหม?
ลี

3
~/.inputrcหรือ/etc/inputrcไฟล์ที่อ้างอิงโดยตัวแปรสภาพแวดล้อม$INPUTRCคือไฟล์กำหนดค่าการแก้ไขบรรทัดของแอปพลิเคชันทั้งหมดที่ใช้ readline รวมถึง bash (เชลล์ของคุณ) มันมีความสามารถในการแก้ไขบรรทัดในตัวรวมถึงสองสิ่งนี้: ในหน้าคู่มือของ bash ค้นหาหนึ่งในคำหลักเหล่านี้เพื่อค้นหาเพิ่มเติม \e[5~/ \e[6~คือลำดับการหลีกเลี่ยงที่สร้างขึ้นโดยปุ่ม Page Up / Down ในตัวจำลองเทอร์มินัลส่วนใหญ่ หากต้องการดูให้เรียกใช้catคำสั่งจากนั้นกดปุ่มเหล่านี้ (ไบต์ escape จะแสดงในเทอร์มินัล^[ในขณะที่อินพุต input \e)
egmont

ตัวอย่างในคำถามเดิมของคุณบอกว่าปุ่มขึ้น / ลงทำงานด้วยวิธีนี้ใน Matlab มันจะน่าสนใจที่จะเห็นสิ่งที่เกิดขึ้นถ้าคุณวางลำดับของขึ้นและลงในอินพุตและกำหนดให้กับการกระทำนี้ มันจะทำงานอย่างถูกต้องหรือมีผลข้างเคียงที่น่ารังเกียจในขณะที่มันขัดแย้งกับพฤติกรรมเริ่มต้นของพวกเขา ฉันไม่รู้ฉันยินดีที่จะได้ยินสิ่งที่คุณค้นพบถ้าคุณทดลองกับสิ่งนี้
egmont

เมื่อฉันทำecho $INPUTRCมันว่างเปล่า ฉันใช้ Ubuntu 14.04
JorgeeFG

2
โดยส่วนตัวฉันชอบที่จะเอาชนะลูกศรขึ้นลงเพื่อทำสิ่งนี้: "\e[A": history-search-backwardและ"\e[B": history-search-forward
1818

9

นอกจากประวัติของ ^ r / ^ i-search:

alt.แทรก "word" สุดท้ายของคำสั่งก่อนหน้าที่เคอร์เซอร์ ทำซ้ำเพื่อให้ได้คำสุดท้ายจากคำสั่งเก่า (แต่โปรดทราบว่าการติดตาม&จะนับเป็นคำสุดท้ายสำหรับคำสั่งพื้นหลัง)

นี้เป็นซุปเปอร์ที่มีประโยชน์สำหรับmkdir foo, cdAlt-dot ได้เร็วขึ้นกว่าลูกศรขึ้น ^ ที่ Alt-d cd(ลบคำไปข้างหน้า)

เพื่อให้ได้คำที่ 2 ถึงสุดท้ายให้ใช้esc - 2 alt+.(เช่นใช้อาร์กิวเมนต์ตัวเลขแบบ emacs เป็นalt+.จำนวนลบนับจากท้ายบวกจำนวนนับไปข้างหน้าตั้งแต่เริ่มต้น) แต่โดยปกติแล้วจะมีปัญหามากกว่าที่มันคุ้มค่า; ในบางจุดการเข้าถึงเมาส์และคัดลอก / วางหรือลูกศรขึ้นเร็วขึ้นและเร็วขึ้นและเป็นส่วนหนึ่งของ ^ w / ^ y (ดูด้านล่าง)


หากเทอร์มินัลของคุณได้รับการตั้งค่าอย่างเหมาะสม / ถูกต้อง ctrl-left และ ctrl-right จะย้อนกลับ / ไปข้างหน้าด้วยคำ ถ้าไม่มีหวังว่าอย่างน้อย alt-b และ alt-f จะทำสิ่งเดียวกัน


ctrl- / เป็นการเลิกทำ คุณสามารถใช้การทำซ้ำอัตโนมัติสำหรับการลบคำได้อย่างมีประสิทธิภาพมากขึ้นหากคุณสามารถเลิกทำเมื่อทำเกินกำหนดสักเล็กน้อย


การผสม / จับคู่คำสั่งที่มีประสิทธิภาพมากขึ้นมาจากการใช้ kill-ring ซึ่งทำงานได้ดีเหมือนกับใน Emacs ctrl-y เพื่อวาง ctrl-w / ctrl-u / ctrl-backspace / alt-d สุดท้าย alt-y เพื่อวนผ่านข้อความที่ถูกฆ่าที่เก่ากว่า

ctrl-w หลายรายการหรืออะไรก็ตามที่อยู่ในแถวทำรายการ kill-ring ใช้ลูกศรซ้ายและขวาหรือบางอย่างเพื่อแยกรายการหากคุณต้องการลบสองสิ่งและวางทีหลังเท่านั้น

คุณสามารถรวมสิ่งเหล่านี้เข้าด้วยกัน

  • เริ่มพิมพ์คำสั่ง
  • ctrl-r เพื่อกลับไปที่คำสั่งเก่าและคว้าส่วนหนึ่งของมันด้วย control-w หรือคล้ายกัน
  • esc-r หรือalt+rเพื่อกู้คืนมันเป็นวิธีก่อนที่คุณจะลบส่วนหนึ่งของมัน
  • alt- >เพื่อไปยังจุดสิ้นสุดของประวัติศาสตร์ (เช่นลูกศรชี้ลงจนสุดทาง) เพื่อกลับไปที่คำสั่งที่คุณอยู่ตรงกลาง

เคล็ดลับการใช้งานแบบโต้ตอบอื่น ๆ :

เปิดใช้งานshopt -s globstarดังนั้นคุณสามารถทำได้**/*.c(เรียกซ้ำรวมถึง dir ปัจจุบัน) บางครั้งมีประโยชน์สำหรับการใช้งานแบบโต้ตอบ แต่มักfind -name '*.c' -exec foo {} +จะดีกว่า

หากคุณเขียนสคริปต์ทุบตีคุณจะพบว่ามีประโยชน์ในการshopt -s extglobเปิดใช้งานในเชลล์เชิงโต้ตอบของคุณเช่นกัน บางครั้งคุณจะพบการใช้งานสิ่งที่ต้องการ*.!(c|h)จับคู่ไฟล์ที่ไม่ได้ลงท้ายด้วย. c หรือ. h

ค้นหานามแฝงที่คุณต้องการสำหรับls -l, lessและสิ่งอื่น ๆ ที่คุณทำมาก ( cp -i, mv -iและrm -Iมีความสุข. อย่ารับในนิสัยของขึ้นอยู่กับพวกเขาที่จะทำ RM เลือก. GNU RM ของ -I ถามครั้งเดียวสำหรับ args ทั้งหมด.)

ฉันชอบalias m=less(m สำหรับ "มากกว่า") ฉันได้lessตั้งค่า,และ.เชื่อมโยงกับไฟล์ก่อนหน้า / ถัดไป ( lesskey) ค่าเริ่มต้นคือลำดับหลายปุ่มกดที่ไม่สามารถใช้กับ autorepeat ได้


ฉันชอบทำทุกอย่างภายในหน้าจอ GNU ฉันพบว่าการติดตามหน้าต่างหน้าจอที่มีหมายเลขง่ายกว่าแท็บจำนวนมากใน Konsole (หรือโปรแกรมจำลองเทอร์มินัลอื่น ๆ ที่ฉันได้ลอง) หากคุณยังไม่รู้screenให้เรียนรู้ tmux เพราะมันใหม่กว่าและน้อยกว่า crufty

เพื่อให้ได้ฟังก์ชั่นการเปิดเชลล์ใหม่ที่มี cwd เหมือนกับเชลล์อื่นฉันใช้hook ที่กำหนดเองสำหรับ cd / pushd / popd ที่ให้ฉันทำcds 8cd กับอะไรก็ตามที่เชลล์ของฉันใช้ในหน้าต่างหน้าจอ 8 สิ่งนี้ใช้ได้แม้กับเปลือกนอกเซสชันหน้าจอตราบใดที่มีเพียงหน้าจอเดียว


ฉันดูเหมือนจะไม่ได้ "กำหนดค่าอย่างเหมาะสม" ทางลัดมากมายที่ฉันเห็นที่นี่ไม่ทำงานฉันใช้เทอร์มินัลหุ้นจาก Ubuntu 14.04 ฉันจะกำหนดค่าได้อย่างไร
JorgeeFG

@ JorgeeFG: ฉันคิดว่ามันใช้ได้กับฉันด้วยgnome-terminalใน Ubuntu 14.04 ก่อนที่ฉันจะเปลี่ยนเป็น KDE ตัวเลือกที่เกี่ยวข้องอยู่ในการตั้งค่าเทอร์มินัลของคุณคำนำหน้าตัวอักษรเทียบกับระดับบิตสูงและการตั้งค่าอื่น ๆ บางคนไม่ทำงานอย่างสมบูรณ์แบบสำหรับฉันผ่าน ssh (เช่น ctrl left / right munge รหัส escape สำหรับปุ่มลูกศรและฉัน5Dปรากฏตัวขึ้นอย่างแท้จริง)
Peter Cordes

7

เพิ่มบรรทัดต่อไปนี้ใน ~/.inputrc

"\e[A": history-search-backward
"\e[B": history-search-forward

สิ่งนี้คล้ายกับคำตอบของ egmont แต่แทนที่จะใช้ Page Up และ Page Down มันใช้ลำดับการยกเว้นสำหรับ Arrow Up และ Arrow Down วิธีนี้สะดวกกว่าการใช้บน Mac


4

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

export HISTSIZE=10000
export HISTTIMEFORMAT="%m/%d/%Y %T "

3

วิธีที่ฉันมักใช้คือรวมhistoryคำสั่งด้วยgrep

IE:

history | grep <command im looking for>

ที่จะแสดงประวัติของคำสั่งที่คุณพิมพ์ซึ่งมีคำสั่งนั้นคุณสามารถใช้:

!<number listed in history command>

เพื่อทำซ้ำคำสั่งนั้น

IE:

history | grep history

142  history
143  history | grep lvresize
568  history | grep echo
570  history | grep echo
571  history | grep history

ติดตามโดย: !571

จะทำซ้ำ history | grep history


1
CR = ดีขึ้น + ปลอดภัยกว่ามาก
PSkocik

1
บางทีโดยส่วนตัวแล้วฉันค้นหาประวัติที่ส่งไปยัง grep เพื่อเป็นวิธีที่รวดเร็วกว่าในการค้นหาคำสั่งส่วนใหญ่ เท่าที่ปลอดภัยกว่าฉันไม่แน่ใจว่าคุณหมายถึงอะไรความเสี่ยงโดยธรรมชาติในการใช้ประวัติตามที่ระบุเพื่อค้นหาผ่าน cR คืออะไร?
น้ำเกรวี่

2
@ Gravy ฉันสงสัยว่า PSkocik หมายถึงการ!ทดแทนประวัตินั้นปลอดภัยน้อยกว่า
Derobert

3
@Gravy ความเสี่ยงที่เกิดขึ้นเองจะทำให้เกิดความผิดพลาด ไม่ทราบสาเหตุที่เทอร์มินัลของคุณค้างไว้ยกเว้นคุณใช้ Control-S และคุณเปิดใช้งานการควบคุมโฟลว์ xon / xoff (มักเป็นค่าเริ่มต้น) ถ้าเป็นเช่นนั้นการควบคุม -Q จะนำมันกลับมา
Derobert

1
ฉันเห็นด้วยกับ @PSkocik cr ดีกว่ามากเพราะง่ายต่อการแก้ไขบรรทัดประวัติแทนที่จะเรียกใช้อีกครั้งด้วยวิธีเดียวกัน การรันคำสั่งที่เหมือนกันอีกครั้งเป็นกรณีเล็ก ๆ น้อย ๆ ของสิ่งที่คุณสามารถทำได้เพื่อประหยัดเวลาในการพิมพ์รูปแบบซ้ำบนหนึ่งซับที่ซับซ้อนหรือแท็บเติมไฟล์ที่แตกต่างในเส้นทางที่ยาว ดูคำตอบของฉัน
Peter Cordes

1

ฉันใช้เคล็ดลับรายวัน 4 ข้อ(และอื่น ๆ )ในเทอร์มินัลทุบตีของฉัน:

  • ดำเนินการคำสั่งสุดท้าย: !!

  • ดำเนินการคำสั่ง N จากประวัติ: !N

  • พิมพ์คำสั่งสุดท้ายที่เริ่มต้นด้วย คำนำหน้า จากประวัติ: !prefix:p

  • ดำเนินการคำสั่งสุดท้ายที่เริ่มต้นด้วย คำนำหน้า จากประวัติ: !prefix


1

ถ้ามันใช้ได้สำหรับคุณzshแทนที่จะbashใช้ cona ให้คุณใช้oh-my-zshเพื่อสิ่งนั้น

มันมีลูกศรขึ้นลงนำทางผ่านประวัติคำสั่งของคุณ มันยังอนุญาตการนำทางเดียวกันนั้นเมื่อคุณพิมพ์ข้อความ (เช่น Mathlab) แล้ว

แก้ไข:นอกจากนี้ยังมีสิ่งที่มุ่งเน้นนักพัฒนาอื่น ๆ เช่นนามแฝงและธีม สิ่งพิเศษนั้นทำให้ distro ใหญ่ขึ้นและซับซ้อนกว่าการใช้งาน

https://github.com/robbyrussell/oh-my-zsh


1
oh-my-zshมีสิ่งของหลายอย่าง คุณอาจจะบอกว่า: คุณสมบัติที่แน่นอนนี้รวมอยู่ใน distro นั้นเมื่อคุณต้องการเพียงแค่การตั้งค่าหรือแอพที่เฉพาะเจาะจง
muru

ฉันแก้ไขโพสต์: ฉันเตือนว่ามันใหญ่กว่าแอพที่เรียบง่าย
user9869932

1

เพิ่มนามแฝงต่อไปนี้ใน ~ / .bashrc

alias h='history | awk '"'"'{$1="";print}'"'"' |sed "s/^ *//" |grep -v "^h " | sort | uniq | grep'

การใช้งาน: h fireจะได้รับรายชื่อของคำสั่งมีไฟ หรือh ^fireจะได้รับรายชื่อของคำสั่งเริ่มต้นด้วยไฟ

สิ่งนี้มีประโยชน์เมื่อฉันต้องการดูชุดคำสั่งในเวลาเดียวกัน

ยัง'"'"'ไงก็น่าเกลียด แต่ฉันไม่สามารถหาวิธีอื่น ๆ เพื่อหลีกเลี่ยงคำพูดเดียวในคำพูดเดียว


fyi - h="history | awk '{\$1=\"\"; print}'ควรได้ผล หรือสร้างฟังก์ชั่นและเรียกมันว่า
DarkHeart

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