วิธีการเพิ่มรูปแบบการทุบตีเสร็จสิ้น (สำหรับ unzip)?


12

เมื่อฉันพิมพ์

unzip <tab>

ฉันได้รับรายชื่อของไฟล์ทั้งหมดที่ลงท้ายด้วย.zipซึ่งเป็นพฤติกรรมมาตรฐานของการทำให้แท็บเสร็จสมบูรณ์สำหรับunzipคำสั่ง

อย่างไรก็ตามฉันยังต้องการทุบตีเสร็จสิ้นสำหรับunzipรายการไฟล์ที่ลงท้าย.udpด้วยนอกเหนือจาก.zipไฟล์ ฉันจะทำพฤติกรรมนี้ในท้องถิ่นของฉันได้.bashrcอย่างไร

คำตอบ:


23

แทนที่จะคอยแสดงความคิดเห็น ...


complete -f -X '!*.@(zip|udp)' unzip

ควรเพิ่มความสมบูรณ์ให้

-f -X '!*.@(zip|udp)'
 |  |  | |||________|
 |  |  | ||     |
 |  |  | ||     +- filterpat: zip or udp
 |  |  | |+-------------  @ : Matches one of the given patterns
 |  |  | +-------------- *. : Anything+<dot>
 |  |  +----------------  ! : Negate
 |  +------------------- -X : Filter out matches in "filterpat"
 +---------------------- -f : files

ในคำอื่น ๆ : ไฟล์ที่สมบูรณ์และลบทั้งหมดที่ไม่สิ้นสุดในหรือ.zip.udp


พิเศษ

ถ้าคุณเพิ่ม-o defaultเสร็จสิ้นจะเสร็จสมบูรณ์ / ตรงกับทุกไฟล์และไดเรกทอรีถ้ามีไม่มีไฟล์ที่ลงท้ายด้วยหรือ.zip.udp

ถ้าคุณเพิ่ม-o plusdirsเสร็จจะเพิ่มไดเรกทอรีใดนอกจากเพื่อการแข่งขันของไฟล์ที่ลงท้ายในที่ใด ๆหรือ.zip.udp

ปัจจุบัน

เมื่อคุณใช้complete -p unzipคุณจะได้รับรูปแบบปัจจุบัน

จากความคิดเห็นของคุณเสียงส่วนใหญ่ดูเหมือนว่าคุณจะขาดหายไป+หรือ@ในรูปแบบเช่นใน:

# Err:
complete -f -X '!*.(zip|udp)' unzip
                   |
                   +---- Missing + or @

ซึ่งจะหมายถึงจับคู่ไฟล์ใด ๆ ที่ลงท้าย.(zip|udp)ด้วย เช่น

touch 'file_test.(zip|udp)'

ดูที่คู่มือในส่วนนี้ด้วย:

มันเป็นไปได้เช่นextglobไม่ได้เปิดใช้งาน เปิดใช้งานโดย:

shopt -s extglob

ตรวจสอบสถานะปัจจุบันของshoptการตั้งค่าทั้งหมดโดยการป้อน:

shopt

ฟังก์ชัน

ถ้านั่น-F somethingหมายความว่ามันใช้ฟังก์ชั่นที่ชื่อว่าบางสิ่งเพื่อสร้างรายการความสำเร็จ

_filedir_xspecโดยปกติจะเป็นฟังก์ชั่นเดเบียน คุณอาจมีสิ่งนี้:

$ cat /etc/bash_completion
. /usr/share/bash-completion/bash_completion

ซึ่งหมายถึง/usr/share/bash-completion/bash_completionรับที่มา ที่นี่คุณจะได้พบกับฟังก์ชั่นในคำถาม อีกไม่กี่บรรทัดคุณจะเห็นว่าฟังก์ชัน / ความสมบูรณ์นี้ถูกเพิ่มโดยฟังก์ชันที่มีชื่อ_install_xspecเช่น:

_install_xspec '!*.@(zip|[ejsw]ar|exe|pk3|wsz|zargo|xpi|s[tx][cdiw]|sx[gm]|o[dt][tspgfc]|od[bm]|oxt|epub|apk|do[ct][xm]|p[op]t[mx]|xl[st][xm])' unzip zipinfo

รายการคู่มือ:


อัปเดตเป็นความคิดเห็น 1:

- ไม่ตรงกันเนื่องจากไฟล์เก็บถาวรหรือการอนุญาตไฟล์ไม่ถูกต้อง

สิ่งนี้ไม่ควรส่งผลกระทบต่อผลลัพธ์ completeจับคู่ไฟล์ที่กำหนดโดยกฎเท่านั้นและไม่ประมวลผลไฟล์ หากคุณสามารถระบุพวกเขาด้วยlsพวกเขาควรจะจับคู่

ในฐานะที่เป็นหมายเหตุด้านหนึ่งสามารถเพิ่มฟังก์ชั่นดังกล่าวโดยใช้ฟังก์ชั่นสมบูรณ์:

function _unzip_validated() {
    # 1. Generate list of files ending in e.g. .zip and .udp
    # 2. Validate each file and remove invalid ones from file list.
}

complete -F _unzip_validated unzip

- สี ทำไมไม่lsเห็นความแตกต่างtest.zipจากtest.upd?

completeนี้ไม่ได้ส่งผลกระทบต่อ สีโดยให้บริการโดยls $LS_COLORSลอง:

echo "$LS_COLORS" | tr : '\n' | sort

คุณควรเห็นสิ่ง*.zip=01;31ที่หมายถึง:

*.zip=01;31
|____| |  |
   |   |  +--- Red
   |   +------ Bold
   +---------- Files with .zip extension

*.udp ในทางกลับกันไม่มีการเชื่อมโยงกับมันดังนั้นจึงไม่มีการระบายสี


ขั้นตอนถัดไป (ควรเป็นก่อน)

  1. เปิดเทอร์มินัลแล้วไปที่ไดเรกทอรีพร้อมไฟล์ทดสอบ ทั้ง. zip และ. udp
  2. เข้าสู่ bash --norc
  3. เข้าสู่ complete -f -X '!*.@(zip|udp)' unzip
  4. เข้าสู่ shopt -s extglob
  5. เข้าสู่ unzip <tab><tab>

ผลลัพธ์?

นอกจากนี้คลิกแก้ไขใต้คำถามของคุณและเพิ่มผลลัพธ์ของ:

bind -V
shopt
env

อาจเป็นประโยชน์


ขอบคุณมากสำหรับคำอธิบายที่ดีและยาว แต่ก็ยังใช้งานไม่ได้ complete -p unzipอัตราผลตอบแทนcomplete -f -X '!*.@(zip|udp)' unzipและเสร็จสมบูรณ์ไฟล์ที่ชื่อว่าunzip <tab> test.zipอย่างไรก็ตามไดเรกทอรีมีไฟล์ชื่อเช่นกันซึ่งไม่ได้พบได้โดยการเสร็จสิ้นแท็บtest.upd unzipความเป็นจริงของการอนุญาตไฟล์หรือความยาวเป็นศูนย์ของไฟล์อาจจะอธิบายพฤติกรรมแปลก ๆ นี้หรือไม่?
อเล็กซ์

@Alex: ควรจะเสร็จสิ้นทั้งไฟล์ที่ว่างเปล่าและไฟล์ที่ถูกต้องเช่นเดียวกับไฟล์ที่ไม่มีสิทธิ์ มันเป็นพฤติกรรมเดียวกันหรือไม่ถ้าคุณเพิ่มเข้าไปในสคริปต์ทดสอบ เช่น 1. สคริปต์ทดสอบบางชุดที่มีชุดการทำงาน: ~/bin/testing, 2. complete -f -X '!*.@(zip|udp)' testing, 3. testing <tab><tab>?
Runium

@Alex: คุณสามารถอัปเดต Q ด้วยผลลัพธ์ของshopt...
Runium

extglobเปิดใช้งานแล้ว ตัวอย่างด้วย 'การทดสอบ' เลือกzipไฟล์อีกครั้ง ฉันสังเกตเห็นว่าtest.zipมีการแสดงเป็นสีแดงในขณะที่test.updจะแสดงในสีขาวด้วยls -lทั้งไฟล์ว่างเปล่าที่มีสิทธิ์เดียวกัน, เจ้าของรถและการเชื่อมโยงกลุ่ม ทำไมไม่lsเห็นความแตกต่างtest.zipจากtest.upd? บางทีนี่อาจเป็นคำใบ้ต่อปัญหาที่ฉันมี?
Alex

@Alex: เพิ่มการอัปเดต
Runium

3

ในไฟล์/etc/bash_completionที่คุณคาดว่าจะมีแหล่งที่มาบางแห่งความสมบูรณ์เริ่มต้นอย่างน้อยสำหรับรุ่นของฉันbash(v4.2.25) คือ

complete -f -X '!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk)' unzip zipinfo

ลองเปลี่ยนนิพจน์ทั้งหมดเป็น

complete -f -X '!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk|udp)' unzip zipinfo

และเพิ่มของคุณ .bash_profile


นี่ไม่ได้แก้ปัญหาของฉัน ถ้าผมทำเช่นนั้นและแหล่งที่มานั้นunzip <tab>ไม่พบ.zipหรือ.updไฟล์หรือไฟล์อื่น ๆ
อเล็กซ์

ลองกดปุ่มแท็บสองครั้งเพื่อดูว่ามันแตกต่างกันหรือไม่ ความสำเร็จอื่น ๆ ทำงานได้อย่างที่คาดไว้หรือไม่? ตัวอย่างเช่นgzipกับ.gzไฟล์?
bsd

แท็บการกดสองครั้งจะไม่เปลี่ยนแปลงอะไรเลย ใช้gunzipกับ.gzไฟล์เลือกเฉพาะไฟล์ที่ลงท้ายด้วยแต่ความหมายยังแตกต่างกัน:.gz complete -F _filedir_xspec gunzip
อเล็กซ์

คุณมาไฟล์/etc/bash_completionในของคุณ.bashrcหรือไม่
bsd

ลองshopt -s extglob
Edward Falk

2

ลองเพิ่มบรรทัดนี้ใน. bashrc ของคุณ:

complete -f -o default -X '!*.+(zip|udp)' unzip

ดูเหมือนว่ามีข้อเสนอแนะนี้ฉันจะค้นหา.udpไฟล์ แต่เฉพาะในกรณีที่ไม่มี.zipไฟล์ หาก a test.zipและtest.udpไฟล์มีอยู่ในไดเรกทอรีปัจจุบันให้unzip <tab>แสดงรายการ.zipไฟล์เท่านั้น ฉันคาดว่าจะเห็นไฟล์ทั้งสอง (เช่น bash เสร็จจะให้test.)
อเล็กซ์

คุณแน่ใจไหม? ฉันตรวจสอบการทุบตีของฉันและดูเหมือนว่าจะพบทั้งไฟล์udpและ zipคุณมา.bashrcหลังจากเพิ่มบรรทัดหรือไม่
mkc

ฉันซ้ำในเทอร์มินัลใหม่และตอนนี้unzip <tab>แสดงรายการไฟล์ทั้งหมดแม้กระทั่งไฟล์ที่ลงท้ายด้วยวลีที่แตกต่างกัน ตอนนี้สิ่งที่ฉันต้องการ
อเล็กซ์

แปลก .. ฉันใช้ GNU bash เวอร์ชั่น 4.2.25 และทำงานได้ตามที่คาดไว้ คุณกำลังทุบตีรุ่นใดอยู่
mkc

คุณช่วยลองเพิ่มสองบรรทัดแยกกันได้complete -f -o default -X '!*.zip' unzipcomplete -f -o default -X '!*.udp' unzip
ไหม

1

ใช้ดีกว่า_filedirแทน complete"ดิบ"

การให้เหตุผล

  • grep _filedir -r $(pkg-config --variable=completionsdir bash-completion) | wc -l
  • tilde ( ~) เส้นทางกำลังถูกขยาย
  • คำนำหน้าจะถูกลบออกสำหรับไดเรกทอรีเช่นสำหรับ/home/tux/Do<TAB><TAB>รายการที่คุณได้รับเป็นคำตอบจะลบ '/ home / tux' และทำให้กะทัดรัดมากขึ้น
  • ง่ายต่อการติดตั้งและไม่ปลอดภัยมากขึ้น

MWE

_unzip_completor()
{
    # init bash-completion's stuff
    _init_completion || return

    # fill COMPREPLY using bash-completion's routine
    _filedir '@(zip|udp)'
}
complete -F _unzip_completor unzip
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.