ติดตั้ง `fzf` แล้ว ต่อไปควรทำอะไร? (2023)
(andrew-quinn.me)- ตัวค้นหาแบบ fuzzy finder บนคอมมานด์ไลน์อย่าง
fzfเป็นเครื่องมือที่ให้ผลตอบแทนต่อเวลาที่ลงทุนแบบเห็นผลทันทีและมีคุณค่าเฉพาะตัว แต่ผู้พัฒนาจำนวนมากมักติดตั้งแล้วก็เลิกใช้ไปเพราะไม่รู้จะใช้อย่างไร - สามารถแทนที่การค้นหาประวัติคำสั่งด้วย
Ctrl+Rด้วย การจับคู่แบบฟัซซีและการแสดงตัวอย่างหลายรายการ เพื่อลดความไม่สะดวกของวิธีเดิมที่ต้องอาศัยการตรงกันของสตริงแบบเป๊ะ ๆ - ใช้
Alt+Cเพื่อทำ fuzzy cd ได้ แม้จะจำชื่อไดเรกทอรีได้เพียงลาง ๆ และยังสร้างเวิร์กโฟลว์เปิดไฟล์ได้ทันทีด้วยชุดคำสั่งvi $(fzf) - เมื่อต่อเข้ากับ
ripgrepผ่านไพป์ ก็สามารถ ค้นหาแบบฟัซซีทุกบรรทัดในทุกไฟล์ แล้วเปิดไฟล์นั้นในเอดิเตอร์ได้ทันที - เป็นเครื่องมือเพิ่มประสิทธิภาพที่ให้ผลทันทีมากจนแม้แต่แนวคิดแบบ 80/20 heuristic ที่แนะนำให้เรียนรู้เครื่องมือ Unix เดิม (
cat,grep,findฯลฯ) ก่อน ก็ยังใช้ไม่ได้ในกรณีนี้
คุณค่าที่ได้ทันทีหลังติดตั้ง fzf
- วิศวกรซอฟต์แวร์สามารถสร้างเครื่องมือมาปรับปรุงงานของตัวเองได้ไม่ยาก แต่ถ้าสลับไปมาระหว่างหลายเครื่องมือและไม่เรียนรู้ให้ลึก ต้นทุนจะยิ่งสะสมเมื่อเวลาผ่านไป
- 80/20 heuristic ที่ดีคือควรเรียนรู้เครื่องมือ Unix รุ่นเก่าอย่าง
cat,ls,cd,grep,cutก่อน และในงานดูแลระบบสมัยใหม่ก็ควรรวมsedกับawkด้วย - แต่
fzfให้ผลตอบแทนต่อเวลาที่ลงทุนแบบทันทีและมีคุณค่าไม่เหมือนใคร จึงอาจถือเป็นข้อยกเว้นของ heuristic นี้ได้ - ประเด็นสำคัญคือฟีเจอร์ที่ใช้ได้ทันทีหลังติดตั้งด้วย
สคริปต์ติดตั้งfzf`` บนสภาพแวดล้อม Ubuntu มาตรฐาน
ผลลัพธ์ทันทีจากคีย์ลัดพื้นฐาน
-
Ctrl+R: เปลี่ยนประวัติคำสั่งเป็นการค้นหาแบบฟัซซี- ในเทอร์มินัล Linux และ Windows ส่วนใหญ่
Ctrl+Rใช้สำหรับ ค้นหาย้อนกลับ ในประวัติคำสั่ง Ctrl+Rแบบเดิมต้องการ การตรงกันอย่างแม่นยำ เพื่อหาคำสั่งที่ต้องการ และแสดงได้เพียง ตัวอย่างครั้งละหนึ่งรายการ ทำให้ถ้าพิมพ์พลาดไปแม้ตัวเดียวก็หาเจอได้ยาก- เมื่อติดตั้ง
fzfแล้ว คีย์ลัดหลายตัวจะถูกแทนด้วยพฤติกรรมที่ดีกว่า และCtrl+Rก็ได้รับการปรับปรุงอย่างมากจากวิธีเดิม - หากติดตั้งผ่านตัวจัดการแพ็กเกจอย่าง
aptการผนวกคีย์ลัดนี้อาจไม่มีให้ จึงเป็นเหตุผลที่ควรใช้สคริปต์ติดตั้งfzf``
- ในเทอร์มินัล Linux และ Windows ส่วนใหญ่
-
Alt+C: ย้ายไปยังไดเรกทอรีที่จำได้ไม่ชัดอย่างรวดเร็วfzfเปลี่ยนAlt+Cให้เป็นคีย์ลัดcdแบบฟัซซีที่ทรงพลังกว่าเดิม- ช่วยให้ย้ายไปยังไดเรกทอรีได้เร็วเมื่อจำพาธที่แน่นอนไม่ได้และนึกออกแค่ชื่อคร่าว ๆ
- มีประโยชน์เมื่ออยู่ในเทอร์มินัลว่าง ๆ แล้วต้องหารีโพซิทอรีหรือไดเรกทอรีงานที่ไม่ได้เปิดมานาน
ตัวคำสั่ง fzf เองและการใช้ร่วมกับเชลล์
-
fzfพื้นฐาน- ถ้ารันคำสั่ง
fzfตรง ๆ มันจะค้นหาแบบฟัซซีในพาธไฟล์แบบสัมพัทธ์โดยอิงจากไดเรกทอรีปัจจุบัน - ถ้าใช้เดี่ยว ๆ ก็มีประโยชน์แค่ประมาณเลือกตำแหน่งไฟล์ จึงยังไม่โดดเด่นมากนัก
- ถ้ารันคำสั่ง
-
vi $(fzf)- หากใช้ร่วมกับ command substitution แบบ
vi $(fzf)ก็สามารถเปิดไฟล์ที่เลือกผ่านการค้นหาแบบฟัซซีในเอดิเตอร์ได้ทันที - วิธีนี้ไม่ได้ผูกกับ
viเป็นพิเศษ และใช้กับเอดิเตอร์ที่ต้องการอย่างemacs,nano,codeเป็นต้น ได้เช่นกัน
- หากใช้ร่วมกับ command substitution แบบ
-
vi $(find . '/' | fzf)- เมื่อใช้
find . '/' | fzfร่วมกับเอดิเตอร์ ก็สามารถค้นหาแบบฟัซซีจากรายการพาธเต็มเพื่อเปิดไฟล์คอนฟิกที่ไม่รู้ว่าอยู่ตรงไหนได้ - เวลาหาไฟล์อย่าง
nginx.confที่จำตำแหน่งไม่ได้ ก็ไม่จำเป็นต้องเดาตามความรู้เรื่อง FHS หรือท่องจำตำแหน่งไว้ แค่ไพป์ผลลัพธ์ของfindเข้าfzfก็พอ - ถ้าค้นหาด้วย
conf$ก็สามารถกรองให้เหลือเฉพาะบรรทัดที่ลงท้ายด้วยconfได้ - หาก
findเจอข้อผิดพลาดPermission deniedจำนวนมากfzfอาจกระตุกอยู่ชั่วครู่ แต่จะกลับมาทำงานได้เองในอีกไม่กี่วินาที - ความหน่วงไม่กี่วินาทีนี้คือสิ่งที่ต้องแลกกับความสะดวกในการหาไฟล์คอนฟิกด้วยวิธีที่เรียบง่ายมาก
- เมื่อใช้
-
vi **<TAB>- ฟีเจอร์นี้มาจากคอมเมนต์บน Hacker News ของ
sigmonsaysโดยอยู่กึ่งกลางระหว่างการแทนคีย์ลัดกับการรันfzfโดยตรง นั่นคือ fuzzy tab completion ที่ใช้ดอกจันสองตัว vi **<TAB>ใช้เลือกไฟล์ได้ในลักษณะคล้ายvi $(fzf)- แต่หลังจากเติมคำสั่งเสร็จแล้ว ยังต้องกด
Enterอีกหนึ่งครั้ง - ทำงานได้ดีใน bash และ zsh แต่ใน
fishอาจใช้ไม่ได้ - ถ้าคุณจำวิธีเรียก
$(fzf)แบบชัดเจนได้ง่ายกว่า ก็อาจไม่ได้ใช้ฟีเจอร์นี้บ่อยนัก
- ฟีเจอร์นี้มาจากคอมเมนต์บน Hacker News ของ
ใช้ fzf กับการย้ายไฟล์ได้ด้วย
-
mv $(fzf) $(fzf)mv $(fzf) $(fzf)เหมาะเมื่อคุณจำไม่ได้แน่ชัดว่าต้องย้ายอะไรและย้ายไปที่ไหน แต่ยังพอมีเบาะแสที่เฉพาะเจาะจงสำหรับทั้งสองอย่าง- วิธีนี้คือเลือกทั้งไฟล์ต้นทางและปลายทางผ่าน
fzfสองครั้ง - จึงอาจกลายเป็นคำสั่งที่หยิบมาใช้บ่อยเวลาจัดวางไฟล์ เช่น ตอนใส่ GIF ลงใน GitHub README
- มีตัวอย่างที่เกี่ยวข้องคือ
finsteminteractive mode README
ใช้ร่วมกับ rg เพื่อค้นหาแบบฟัซซีถึงเนื้อหาในไฟล์
-
rg:grepที่เร็วและค้นหาแบบ recursive เป็นค่าเริ่มต้น- ชุดคำสั่งด้านล่างทำกับ
grepก็ได้ แต่rgหรือripgrepเหนือกว่าในงานลักษณะนี้เพราะค้นหาแบบ recursive เป็นค่าเริ่มต้น - ถ้าจะทำตามตัวอย่าง แนะนำให้ติดตั้งและใช้
rg
- ชุดคำสั่งด้านล่างทำกับ
-
rg . | fzfrg .จะส่งออกแต่ละบรรทัดจากไฟล์ต่าง ๆ เป็นผลการค้นหา และเมื่อส่งต่อเข้าfzfก็จะค้นหาแบบฟัซซีได้ในทุกบรรทัดของทุกไฟล์- จึงเป็นการค้นหาโดยอาศัยเนื้อหาภายในบรรทัด แทนที่จะอาศัยชื่อไฟล์
-
rg . | fzf | cut -d ":" -f 1- ถ้านำผลที่เลือกจาก
rg . | fzfไปต่อด้วยcut -d ":" -f 1ก็จะคืนค่าฟิลด์แรกตามตัวคั่นโคลอน หรือก็คือตำแหน่งไฟล์ - เป็นชุดคำสั่งสำหรับค้นหาแบบฟัซซีจากเนื้อหาบรรทัด แล้วดึงออกมาเฉพาะพาธของไฟล์ที่มีบรรทัดนั้น
- ถ้านำผลที่เลือกจาก
-
vim $(rg . | fzf | cut -d ":" -f 1)vim $(rg . | fzf | cut -d ":" -f 1)คือการค้นหาแบบฟัซซีในทุกบรรทัดของทุกไฟล์ แล้วเปิดไฟล์ที่มีบรรทัดที่เลือกด้วยvim- ช่วยให้เปิดเอดิเตอร์ต่อได้ทันทีเมื่อจำชื่อไฟล์ไม่ได้ แต่จำเนื้อหาบางส่วนได้
1 ความคิดเห็น
ความคิดเห็นจาก Lobste.rs
ดูเหมือนว่ากลุ่มผู้อ่านเป้าหมายของบทความนี้จะเป็นผมพอดี ติดตั้ง fzf แล้วคิดว่า “อัจฉริยะมาก” แต่สุดท้ายก็ลืมใช้มันอยู่เรื่อย ๆ ตอนนี้อาจจะได้เริ่มใช้จริงแล้วก็ได้
อาจจะเป็นบทความที่ดี แต่ถ้าเป้าหมายคือจะตอบคำถามว่า “แล้วจะทำอะไรต่อดี?” การเริ่มจากการผสานรวมกับเชลล์ของ fzfกลับให้ความรู้สึกว่ากำลังคุยกับผู้อ่านกลุ่มที่แคบลงไปอีก
ผมคุ้นกับการใช้ ctrl-r ใน bash อยู่แล้ว จะให้เปลี่ยนเลยก็ดูเรียกร้องมากเกินไป น่าจะเริ่มจากสอนวิธีฝึกใช้พฤติกรรมแบบเดิมโดยไม่ต้องแทนที่ค่าเริ่มต้นก่อน
ctrl-r น่าจะเป็นคำสั่งที่ผมใช้บ่อยที่สุด และ fzf ก็เป็นการปรับปรุงที่เข้าที่ทันทีโดยแทบไม่มีช่วงเรียนรู้ พอมันรันผ่าน ctrl-r ก็เลยไม่ลืมใช้ fzf ด้วย แต่ต่อมาผมย้ายไปใช้ Fish shell ซึ่งที่นั่นมีพฤติกรรมแบบเดียวกันมาให้เป็นค่าเริ่มต้นอยู่แล้ว
โอเค เชื่อแล้ว อีกไม่นานจะเพิ่มการผสานรวมกับเชลล์ของ fzf และวันนี้ก็ได้เรียนรู้อะไรใหม่หนึ่งอย่าง
เวลาอยากหาไฟล์มาใส่ในคำสั่ง ก็ใช้**คีย์ลัด
ctrl-t**ได้เหมือนกัน ผมใช้กับgitบ่อยเวลาจะเลือกไฟล์ที่จะรวมในบางการเปลี่ยนแปลง และเคยใช้กรองผลลัพธ์จากgrepเพื่อให้ขอบเขตการค้นหาแคบลงด้วยนอกจากการค้นหาประวัติในเชลล์ที่ดีขึ้นแล้ว ผมยังใช้
fzfร่วมกับaliasสองตัวนี้มาตลอดalias gbd='git -c color.ui=never branch | fzf | xargs -I {} git branch -D {}'ส่วนใหญ่ใช้เลือกชุด local branch ที่จะลบทิ้งหลัง merge pull request เสร็จ อาจมีวิธีที่ดีกว่านี้ แต่จนถึงตอนนี้ก็ยังไม่เคยพลาด
alias awp='export AWS_PROFILE="$(grep -e "\[\(.*\)\]" ~/.aws/config | sed -e "s/\[//g" | sed -e "s/\]//g" | cut -d " " -f 2 | sort -u | fzf)"'มันช่วยให้สลับAWS_PROFILEได้อย่างรวดเร็วตามค่าที่อยู่ใน
~/.aws/configตอนนี้กำลังคิดว่าจะทำ alias คล้าย ๆ กันไว้สลับ Kubernetes namespace ด้วยถ้าใช้ปลั๊กอิน fzf.vim ก็จะใช้ fzf ภายใน vim ได้ ไม่ใช่แค่เปิดไฟล์ แต่ยัง fuzzy search กับบัฟเฟอร์ ประวัติคำสั่ง และเนื้อหาไฟล์ได้ด้วย
การใช้งานหลักของ fzf สำหรับผมคือไล่ดูและค้นหาประวัติ commit ของ Gitแบบเชิงเส้น เพื่อดูว่าเมื่อไม่นานมานี้มีอะไรเปลี่ยนไปบ้าง
ในการตั้งค่า Git ปกติของผม ผมกำหนด
git fzfไว้แบบนี้เหมือนผมจะพลาดอะไรบางอย่างไป สงสัยว่าถ้ายังไม่รู้ว่าจะเอาไปทำอะไร ทำไมถึงติดตั้ง fzfตั้งแต่แรก
มีโพสต์ที่เกี่ยวข้องล่าสุดเหมือนกัน มีผู้ใช้คนหนึ่งใช้ fzf เป็นตัวเลือกไฟล์สำหรับ jj
https://lobste.rs/s/exlogg/jjj