1 คะแนน โดย GN⁺ 4 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ทันทีหลังติดตั้ง fzf จะช่วยปรับปรุงการค้นหาประวัติคำสั่งด้วย Ctrl+R ให้เป็นการค้นหาแบบฟัซซี
  • ใช้ Alt+C เพื่อย้ายไปยังไดเรกทอรีทำงานเก่า ๆ ได้อย่างรวดเร็วโดยไม่ต้องรู้พาธแบบเป๊ะ ๆ
  • คำสั่ง fzf สามารถใช้ร่วมกับ การแทนที่คำสั่ง เพื่อเปิดไฟล์ที่เลือกได้ทันทีด้วย vi, emacs, code
  • เมื่อส่งผลลัพธ์จาก find เข้า fzf จะช่วยให้หาไฟล์คอนฟิกที่ไม่รู้ตำแหน่ง เช่น nginx.conf ได้ง่ายขึ้น
  • rg. | fzf ช่วยให้เปิดไฟล์ที่ต้องการได้จากเบาะแสเป็นบรรทัดเนื้อหาในไฟล์ แทนที่จะอาศัยชื่อไฟล์

คุณค่าที่ได้ทันทีหลังติดตั้ง fzf

  • วิศวกรซอฟต์แวร์สามารถสร้างเครื่องมือเพื่อปรับปรุงงานของตัวเองได้ไม่ยาก แต่ถ้าสลับไปมาระหว่างหลายเครื่องมือโดยไม่ได้ฝึกใช้ให้ลึก ต้นทุนจะยิ่งสะสมเมื่อเวลาผ่านไป
  • กฎ 80/20 ที่ดีคือควรเรียนรู้เครื่องมือ Unix รุ่นเก่าอย่าง cat, ls, cd, grep, cut ให้คล่องก่อน และในบทบาทดูแลระบบสมัยใหม่ก็มักรวม sed และ awk ด้วย
  • fzf ถือเป็นข้อยกเว้นของกฎนี้ เพราะให้ผลลัพธ์คุ้มค่าทันทีและมีคุณค่าเฉพาะตัว
  • ประเด็นสำคัญคือฟังก์ชันที่ใช้งานได้ทันทีหลังติดตั้งด้วย สคริปต์ติดตั้ง fzf บนสภาพแวดล้อม Ubuntu มาตรฐาน

ผลลัพธ์ทันใจจากคีย์ลัดพื้นฐาน

  • Ctrl+R: เปลี่ยนประวัติคำสั่งให้ค้นหาแบบฟัซซี

    • ในเทอร์มินัล Linux และ Windows ส่วนใหญ่ Ctrl+R ใช้สำหรับ ค้นหาย้อนกลับ ในประวัติคำสั่ง
    • Ctrl+R แบบเดิมต้องการ การตรงกันแบบเป๊ะ เพื่อหาคำสั่งที่ต้องการ และแสดง ตัวอย่างล่วงหน้าได้ครั้งละหนึ่งรายการ เท่านั้น ทำให้ถ้าพิมพ์พลาดไปแค่ตัวอักษรเดียวก็หาได้ยาก
    • เมื่อติดตั้ง fzf แล้ว คีย์ลัดหลายตัวจะถูกแทนที่ด้วยพฤติกรรมที่ดีกว่าเดิม และ Ctrl+R ก็ได้รับการปรับปรุงอย่างมากเช่นกัน
    • หากติดตั้งผ่านตัวจัดการแพ็กเกจอย่าง apt การผนวกคีย์ลัดนี้อาจไม่มีให้ จึงเป็นเหตุผลที่ควรใช้ สคริปต์ติดตั้ง fzf
  • Alt+C: ย้ายไปยังไดเรกทอรีที่จำได้ลาง ๆ อย่างรวดเร็ว

    • fzf จะยกระดับ Alt+C ให้เป็นคีย์ลัด cd แบบฟัซซีที่ทรงพลังกว่าเดิม
    • ช่วยให้ย้ายไปยังไดเรกทอรีได้อย่างรวดเร็วเมื่อจำชื่อได้คร่าว ๆ แต่จำพาธที่แน่นอนไม่ได้
    • มีประโยชน์เมื่ออยู่ในเทอร์มินัลว่าง ๆ แล้วต้องการหารีโพซิทอรีหรือไดเรกทอรีทำงานที่ไม่ได้เข้าไปนานแล้ว

ตัวคำสั่ง fzf เองและการประกอบกับเชลล์

  • fzf พื้นฐาน

    • เมื่อรันคำสั่ง fzf ตรง ๆ มันจะค้นหาแบบฟัซซีในพาธไฟล์สัมพัทธ์โดยอิงจากไดเรกทอรีปัจจุบัน
    • ถ้าใช้เดี่ยว ๆ ก็เป็นเพียงการเลือกตำแหน่งไฟล์ จึงอาจยังไม่เห็นประโยชน์มากนัก
  • vi $(fzf)

    • หากใช้ร่วมกับการแทนที่คำสั่งอย่าง vi $(fzf) ก็จะสามารถเปิดไฟล์ที่เลือกผ่านการค้นหาแบบฟัซซีในเอดิเตอร์ได้ทันที
    • วิธีนี้ไม่ได้พิเศษเฉพาะ vi แต่ใช้กับเอดิเตอร์ที่ต้องการอย่าง emacs, nano, code ได้เช่นกัน
  • vi $(find . '/' | fzf)

    • หากนำ find . '/' | fzf ไปใช้ร่วมกับเอดิเตอร์ ก็จะเปิดไฟล์คอนฟิกที่ไม่รู้ตำแหน่งได้โดยค้นหาแบบฟัซซีจากรายชื่อพาธทั้งหมด
    • เวลาต้องหาไฟล์อย่าง nginx.conf ที่จำตำแหน่งไม่ได้ ก็ไม่จำเป็นต้องเดาตามความรู้เรื่อง FHS หรือท่องจำไว้ แค่ส่งผลลัพธ์จาก find เข้า fzf ก็พอ
    • หากค้นหาด้วยคำอย่าง conf$ ก็สามารถกรองให้เหลือเฉพาะบรรทัดที่ลงท้ายด้วย conf ได้
    • ถ้า find เจอข้อผิดพลาด Permission denied จำนวนมาก fzf อาจสะดุดชั่วคราว แต่จะกลับมาทำงานได้หลังผ่านไปไม่กี่วินาที
    • ความหน่วงไม่กี่วินาทีนี้เป็นการแลกกับความสะดวกในการหาไฟล์คอนฟิกด้วยวิธีที่เรียบง่ายมาก
  • vi **<TAB>

    • จาก คอมเมนต์บน Hacker News ของ sigmonsays มีฟีเจอร์หนึ่งที่อยู่กึ่งกลางระหว่างการแทนที่คีย์ลัดกับการรัน fzf โดยตรง นั่นคือ การเติมแท็บแบบฟัซซีด้วยเครื่องหมายดอกจันสองตัว
    • vi **<TAB> ใช้เลือกไฟล์ได้ในลักษณะคล้าย vi $(fzf)
    • หลังจากคำสั่งถูกเติมให้สมบูรณ์แล้ว ยังต้องกด Enter อีกหนึ่งครั้ง
    • ทำงานได้ดีใน bash และ zsh แต่ใน fish อาจใช้งานไม่ได้ในบางกรณี
    • ถ้าคุณรู้สึกว่าวิธีเรียก $(fzf) แบบชัดเจนจำง่ายกว่า ก็อาจไม่ได้ใช้ฟีเจอร์นี้บ่อยนัก

ใช้ fzf กับการย้ายไฟล์ได้ด้วย

  • mv $(fzf) $(fzf)

    • mv $(fzf) $(fzf) เหมาะในกรณีที่จำไม่ได้แน่ชัดว่าต้องย้ายอะไรและย้ายไปที่ไหน แต่มีเบาะแสที่เฉพาะเจาะจงพอสำหรับทั้งสองฝั่ง
    • วิธีนี้คือเลือกทั้งต้นทางและปลายทางผ่าน fzf สองครั้ง
    • อาจได้ใช้บ่อยเวลาจัดวางไฟล์ เช่น ตอนเพิ่ม GIF ลงใน GitHub README
    • ตัวอย่างที่เกี่ยวข้องคือ README โหมดอินเทอร์แอกทีฟของ finstem

ใช้ร่วมกับ rg เพื่อค้นหาแบบฟัซซีถึงเนื้อหาในไฟล์

  • rg: grep แบบเร็วที่ค้นหาแบบ recursive เป็นค่าเริ่มต้น

    • การจับคู่ด้านล่างสามารถทำด้วย grep ได้เช่นกัน แต่ rg หรือ ripgrep มีจุดเด่นสำหรับงานนี้เพราะค้นหาแบบ recursive เป็นค่าเริ่มต้น
    • ถ้าต้องการลองตามตัวอย่าง แนะนำให้ติดตั้งและใช้ rg
  • rg . | fzf

    • rg . จะส่งออกแต่ละบรรทัดของไฟล์ต่าง ๆ เป็นผลการค้นหา และเมื่อส่งต่อไปยัง fzf ก็จะค้นหาแบบฟัซซีได้ในทุกบรรทัดของทุกไฟล์
    • นั่นหมายถึงคุณสามารถหาไฟล์จากเบาะแสในบรรทัดเนื้อหาภายในไฟล์ ไม่ใช่จากชื่อไฟล์
  • rg . | fzf | cut -d ":" -f 1

    • หากต่อ cut -d ":" -f 1 เข้ากับผลลัพธ์ที่เลือกจาก rg . | fzf ก็จะคืนค่าฟิลด์แรกที่คั่นด้วยโคลอน หรือก็คือตำแหน่งไฟล์
    • เป็นชุดคำสั่งที่ค้นหาแบบฟัซซีจากเนื้อหาบรรทัด แล้วดึงมาเฉพาะพาธของไฟล์ที่มีบรรทัดนั้นอยู่
  • vim $(rg . | fzf | cut -d ":" -f 1)

    • vim $(rg . | fzf | cut -d ":" -f 1) คือการค้นหาแบบฟัซซีในทุกบรรทัดของทุกไฟล์ แล้วเปิดไฟล์ที่มีบรรทัดที่เลือกด้วย vim
    • เมื่อจำชื่อไฟล์ไม่ได้แต่จำบางส่วนของเนื้อหาได้ ก็สามารถไปต่อยังเอดิเตอร์ได้ทันที

1 ความคิดเห็น

 
GN⁺ 4 시간 전
ความคิดเห็นจาก Lobste.rs
  • ดูเหมือนว่ากลุ่มผู้อ่านเป้าหมายของบทความนี้จะเป็นผมพอดี ติดตั้ง fzf แล้วคิดว่า “อัจฉริยะมาก” แต่สุดท้ายก็ลืมใช้มันอยู่เรื่อย ๆ ตอนนี้อาจจะได้เริ่มใช้จริงแล้วก็ได้

    • ประเด็นสำคัญคือการผนวกมันเข้ากับการตั้งค่าเชลล์เดิม สคริปต์ส่วนตัว และ alias ต่าง ๆ ผมใช้ fzf ตลอด แต่แทบไม่เคยรันมันตรง ๆ เลย
  • อาจจะเป็นบทความที่ดี แต่ถ้าเป้าหมายคือจะตอบคำถามว่า “แล้วจะทำอะไรต่อดี?” การเริ่มจากการผสานรวมกับเชลล์ของ fzfกลับให้ความรู้สึกว่ากำลังคุยกับผู้อ่านกลุ่มที่แคบลงไปอีก
    ผมคุ้นกับการใช้ ctrl-r ใน bash อยู่แล้ว จะให้เปลี่ยนเลยก็ดูเรียกร้องมากเกินไป น่าจะเริ่มจากสอนวิธีฝึกใช้พฤติกรรมแบบเดิมโดยไม่ต้องแทนที่ค่าเริ่มต้นก่อน

    • ที่จริงแล้วมันใกล้เคียงกับค่าเริ่มต้นแบบอัปเกรดมากกว่า ปล่อยให้มันมาแทน ctrl-r นั่นแหละถูกแล้ว และเสน่ห์หลักครึ่งหนึ่งก็คือการคงพฤติกรรมที่คุ้นมือไว้ ขณะที่ได้ประสบการณ์ที่สมบูรณ์ขึ้นในโฟลว์ที่แทบเหมือนเดิม
      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 ไว้แบบนี้

    [alias]  
      # Browse commit history with fzf  
      # Inspired by: https://chrismanbrown.gitlab.io/67.html  
      fzf = "!git log --oneline --color=always --decorate=short $@ | \  
          fzf --ansi --reverse --no-sort \  
            --preview 'git show --color=always {1}' \  
            --preview-window '<50(down)' \  
            --bind 'enter:become(git show {1})' #"  
    
  • เหมือนผมจะพลาดอะไรบางอย่างไป สงสัยว่าถ้ายังไม่รู้ว่าจะเอาไปทำอะไร ทำไมถึงติดตั้ง fzfตั้งแต่แรก

  • มีโพสต์ที่เกี่ยวข้องล่าสุดเหมือนกัน มีผู้ใช้คนหนึ่งใช้ fzf เป็นตัวเลือกไฟล์สำหรับ jj
    https://lobste.rs/s/exlogg/jjj