จะสร้างวลีพิเศษที่ขยายได้ใน bash ได้อย่างไร


12

ฉันพบว่าตัวเองทำ<command> --help | grep <feature>บ่อยมากทุกวัน ฉันสงสัยว่ามันเป็นไปได้ไหมที่จะทำสิ่ง^^ที่ขยายออกไป"--help | grep"จากนั้นฉันก็ทำสิ่งนี้:

ls ^^ size

ที่จะดำเนินการดังต่อไปนี้:

ls --help | grep size

คำตอบ:


15

ด้วยzshคุณจะต้องใช้ชื่อแทนส่วนกลาง :

$ alias -g '^^=--help|grep --color -i'
$ ls ^^ size
     --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
                              1,048,576 bytes; see SIZE format below
 -h, --human-readable       with -l and/or -s, print human readable sizes
 -s, --size                 print the allocated size of each file, in blocks
 -S                         sort by file size, largest first
     --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
 -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
The SIZE argument is an integer and optional unit (example: 10K is 10*1024)

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

  1. ใส่ประวัติด้วยข้อความที่คุณต้องการแทนที่และอักขระพิเศษที่คุณไม่น่าจะใช้เป็นอย่างอื่น (เช่น£ที่นี่เกิดขึ้นบนคีย์บอร์ดของฉัน):

     $ --help $(: £)|grep
     bash: --help: command not found
     Usage: grep [OPTION]... PATTERN [FILE]...
     Try 'grep --help' for more information.
    
  2. จากนั้นใช้การขยายประวัติเพื่อดึงข้อมูลที่:

    $ ls !?£? size
    ls --help $(: £)|grep size
         --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
     -h, --human-readable   with -l and/or -s, print human readable sizes
     -s, --size             print the allocated size of each file, in blocks
     -S                     sort by file size, largest first
         --sort=WORD        sort by WORD instead of name: none (-U), size (-S),
     -T, --tabsize=COLS     assume tab stops at each COLS instead of 8
    

หรือคุณสามารถreadlineขยายได้--help|grepเมื่อกดปุ่มหรือปุ่มตามลำดับ เพื่อที่จะนำไปใช้กับbashเท่านั้น (และไม่ใช่แอปพลิเคชันอื่น ๆ เช่นการgdbใช้ readline) คุณสามารถใช้bindคำสั่ง bash builtin ซึ่งเป็นbashAPI ของการกำหนดค่าreadlineตัวอย่างเช่นใน~/.bashrc:

bind '"^^": "--help|grep "'

หรือเพิ่มลงใน~/.inputrc(ไฟล์กำหนดค่าของ readline):

$if Bash
"^^": "--help|grep "
$endif

(มีเชลล์อื่น ๆ เช่นrcหรือesที่ใช้ readline และในกรณีที่การเชื่อมโยงนั้นอาจสมเหตุสมผล แต่ AFAICT พวกเขาไม่ได้ตั้งค่าrl_readline_nameตัวแปรก่อนที่จะเรียกreadlineดังนั้นคุณจะไม่สามารถเพิ่ม$ifคำสั่งบางอย่างสำหรับพวกเขา (พวกเขาจะแสดงotherเหมือนแอปพลิเคชันทั้งหมด ใช้ readline โดยไม่แจ้งชื่อแอปพลิเคชันของตน))

โปรดทราบว่าคุณต้องป้อนวินาที^ภายในครึ่งวินาที (โดยค่าเริ่มต้น) หลังจากอันแรกเพื่อให้การแทนที่เกิดขึ้น


คุณช่วยอธิบายเกี่ยวกับโซลูชัน readline ได้มากกว่านี้ไหม?! ฉันควรเพิ่มการเชื่อมโยงนั้นที่ไหน แอปพลิเคชันใดที่จะเพิ่มการเชื่อมโยง
yukashima huksay

@yukashimahuksay โปรดดูการแก้ไข
Stéphane Chazelas

17

คุณสามารถใช้ฟังก์ชัน bash เพื่อ:

ใส่สิ่งต่อไปนี้ใน ~ / .bashrc ของคุณ:

qh() {
    type -all "$1" ; { man "$1" || "$1" --help ;} | egrep -i -- "$2"
}

เมื่อคุณบันทึกสิ่งที่คุณbashrc ทำsource ~/.bashrcแล้วคุณสามารถทำได้:

$ qh ls size
      --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                               '--block-size=M' prints sizes in units of
  -h, --human-readable       with -l and/or -s, print human readable sizes
  -s, --size                 print the allocated size of each file, in blocks
  -S                         sort by file size, largest first
      --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
  -T, --tabsize=COLS         assume tab stops at each COLS instead of 8

1
คุณควรเสนอราคา $ 1 และ $ 2 ฉันจะเปลี่ยนสิ่งนี้เป็น: qh () { type -all "$1" ; { "$1" --help || man "$1" ;} | egrep -i -- "$2" ;} # คุณสามารถทำได้: ขนาดของ qh ls, qh ls "บางอย่าง | อื่น ๆ " เป็นต้น (ตัวเลือก) type -all "$1"ยังเพิ่มข้อมูลเกี่ยวกับ $ 1: มันบอกว่าถ้าคุณจะเปิดตัวนามแฝง, ฟังก์ชั่นและ คำสั่ง ฯลฯ และให้ข้อมูลจากมนุษย์ "$ 1" หากคำสั่ง $ 1 ไม่มีตัวเลือก "--help" (เกิดขึ้นบางครั้ง)
Olivier Dulac

1
@OlivierDulac คุณช่วยอธิบายเพิ่มเติมเล็กน้อยเกี่ยวกับประเภท -all "$ 1" ได้ไหม? ในกรณีใดจะจำเป็น?
tgwtdt

รุ่นของฉันประเภท (kubuntu 16.04) รู้เกี่ยวกับ-aแต่ไม่ได้พูดอะไรเกี่ยวกับ-lหรือ-allแต่ฟังก์ชั่นการทำงาน
Joe

8

คุณสามารถใช้การโยง readline:

เพิ่มบรรทัดที่ชอบ

"^^": "--help | grep "

ถึง ~ / .inputrc ของคุณ

จากนั้นกด ^ X ^ R ในเทอมของคุณและการเชื่อมจะถูกเปิดใช้งาน

Keying ในขณะนี้จะส่งผลให้ls ^^ls --help | grep


ฉันตอบก่อนที่ฉันจะเห็นว่า Stephane ได้เพิ่มโซลูชัน readline ฉันลบคำตอบของฉันแล้ว แต่ก็ไม่ถูกลบออกเมื่อฉันเห็นความคิดเห็นถามเกี่ยวกับรายละเอียดเกี่ยวกับวิธีแก้ปัญหา readline
Alex Stragies

2
ตอนนี้ฉันได้เพิ่มอีกในคำตอบของฉัน
Stéphane Chazelas

1
คำตอบที่ตรงเป้าหมายเช่นของคุณและคำตอบที่ครอบคลุมเช่นStéphaneทั้งสองมีสถานที่ของพวกเขา มี upvote!
บิชอป

5

ใช้lessเพื่อดูข้อความช่วยเหลือ

คุณอาจพบว่ามีประโยชน์ในการดูบริบทโดยรอบของบรรทัดที่ตรงกับคำค้นหาของคุณ

hh () { "${1}" --help | less -p "${2}" ; }

ไวยากรณ์ที่เรียกbashใช้ฟังก์ชันนี้คล้ายกับฟังก์ชันqhในคำตอบของ @ tgwtdt โดยมีอาร์กิวเมนต์แรกเป็นคำสั่งให้ตรวจสอบและอาร์กิวเมนต์ที่สองเป็นคำค้นหา ตัวอย่างเช่น:

hh ls size
hh ls "symbolic link"

วิธีนี้จะเปิดข้อความช่วยเหลือแบบเต็มlessไฮไลต์อินสแตนซ์ทั้งหมดของข้อความค้นหาและเลื่อนไปที่อินสแตนซ์แรกของข้อความค้นหา จากนั้นคุณสามารถกดnเพื่อเลื่อนไปข้างหน้าไปยังบรรทัดถัดไปที่มีข้อความค้นหาnอีกครั้งสำหรับข้อความถัดไปและอื่น ๆ Nเพื่อเลื่อนกลับไปอินสแตนซ์ก่อนหน้านี้กด ใช้Home, End, Page Up, Page Down, Up ArrowและDown Arrowปุ่มสำหรับการนำทางทั่วไป กดqหรือQเพื่อออกlessและกลับไปที่บรรทัดคำสั่ง


3

ฉันชอบวิธีแก้ปัญหาโดย @tgwtdt ดังนั้นฉันจึงปรับปรุงมันเล็กน้อย

สิ่งนี้ทำสิ่งเดียวกัน แต่ทำเพียงเล็กน้อยเพื่อจัดการข้อผิดพลาดและพยายามประมวลผลบิวด์อิน

qh ใช้ () แทน {} ดังนั้น qh1 () และ out เป็น local (เป็น subshell)

function qh () (
    function qh1 () {
      out="$(help "$1" 2>&1 )"
      [ $? -ne 0 ] && return 1
      echo "$out"
    }

    type -all "$1" ; { qh1 "$1" || "$1" --help 2>/dev/null || man "$1" 2>/dev/null ;} | egrep -i -- "$2"
) 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.