วิธีจับคู่รูปแบบที่ไม่สนใจตัวพิมพ์เล็กกับ ls


57

ฉันต้องการแสดงรายการไฟล์ทั้งหมดที่ตรงกับรูปแบบที่กำหนดโดยไม่สนใจเคส

ตัวอย่างเช่นฉันรันคำสั่งต่อไปนี้:

ls *abc*

ฉันต้องการดูไฟล์ทั้งหมดที่มี "abc" เป็นส่วนหนึ่งของชื่อไฟล์โดยไม่สนใจขนาดตัวพิมพ์

-rw-r--r-- 1 mtk mtk 0 Sep 21 08:12 file1abc.txt
-rw-r--r-- 1 mtk mtk 0 Sep 21 08:12 file2ABC.txt

บันทึก

ฉันได้ค้นหาหน้าคนสำหรับกรณี แต่ไม่พบอะไรเลย

คำตอบ:


65

lsนี้จะกระทำจริงโดยเปลือกของคุณไม่ได้โดย

ในbashคุณจะใช้:

shopt -s nocaseglob

และจากนั้นเรียกใช้คำสั่งของคุณ

หรือในzsh:

unsetopt CASE_GLOB

หรือใน yash:

set +o case-glob

แล้วคำสั่งของคุณ

คุณอาจต้องการที่จะนำเข้าสู่ที่.bashrc, .zshrcหรือ.yashrcตามลำดับ

อีกทางเลือกหนึ่งด้วย zsh:

setopt extendedglob
ls -d -- (#i)*abc*

(นั่นคือการเลี้ยวแบบไม่คำนึงถึงขนาดตัวพิมพ์แบบตัวพิมพ์แต่ละตัว)

ด้วย ksh93:

ls -d -- ~(i:*abc*)

คุณต้องการให้globbingทำงานแตกต่างกันไม่ได้lsเนื่องจากไฟล์ทั้งหมดถูกส่งผ่านlsโดยเชลล์


ในทุบตีวิธีการรีเซ็ตการตั้งค่าดั้งเดิมถ้าฉันใช้shport -s nocaseglob?
mtk

6
@mtk: ในการตั้งค่าตัวเลือกคุณใช้shopt -s; เพื่อล้างค่าshopt -uมันคุณใช้ หรือคุณสามารถตัดทุกอย่างใน subshell โดยใช้เพื่อให้การตั้งค่าจะไม่ส่งผลกระทบต่อเปลือกแม่:( ) (shopt -s nocaseglob ; ls *abc*)
ruakh

ดังนั้นจึงไม่มีวิธีพกพาสำหรับสิ่งนี้ใน POSIX หรือ SUS หรืออะไรแบบนั้น (ยกเว้น[aA][bB][cC])?
ทิโมธี Gu

วิธีแก้ปัญหาที่ยอดเยี่ยมฉันไม่อยากจะเชื่อเลยว่าฉันไม่เคยเจอshoptคำสั่งในช่วง 15 ปีที่ผ่านมาของการใช้ทุบตี!
Reza Sanaie

คำตอบของ Jfg956 เป็นคำตอบที่ถูกต้อง (อันถัดไป) ทำไมการเปลี่ยนพฤติกรรมของเชลล์เมื่อคุณมี regexp
EnzoR

20

ตามที่อธิบายโดย polemon มันคือเชลล์ (ไม่ใช่ ls) ที่ขยาย*abc*ไปยังรายการไฟล์ นี้เรียกว่ารูปแบบการจับคู่

*นอกเหนือจากการเปลี่ยนรูปแบบทั้งพฤติกรรมการจับคู่ที่จะไม่สนใจกรณีที่คุณสามารถใช้รูปแบบของการจับคู่รูปแบบกว่าอีก ต่อไปนี้จะทำสิ่งที่คุณต้องการในการทุบตี:

ls *[aA][bB][cC]*

จากคนทุบตี:

[... ] จับคู่หนึ่งในอักขระที่ล้อมรอบ

นี้จะช่วยให้การจับคู่เม็ดละเอียดเพิ่มเติมที่คุณสามารถใช้*[aA][bB]c*เพื่อให้ตรงกับabcหรือABcแต่ไม่หรือabC ABCหรือตัวอย่างในภาษาฝรั่งเศสที่ฉันต้องการจับคู่อินสแตนซ์ทั้งหมดของeตัวละคร:

ls *[eéèêëEÉÈÊË]*

1
แต่น่าเสียดายที่วิธีการดังกล่าวกลายเป็นเรื่องที่รวดเร็วอย่างไม่น่าเชื่อเมื่อรูปแบบเริ่มยาวขึ้น แต่สำหรับสิ่งสั้น ๆ มันใช้งานได้
Derobert

@derobert: เป็นความจริงโดยเฉพาะอย่างยิ่งโดยเฉพาะอย่างยิ่ง (และอาจเป็นกรณีนี้) เชลล์ได้ปรับการจับคู่เคสที่ไม่สนใจโดยการใส่ชื่อไฟล์ทั้งหมดและคำขอการจับคู่เป็นตัวพิมพ์เล็กก่อนเปรียบเทียบ อย่างไรก็ตาม[...]สามารถมีประโยชน์ในหลายกรณีและฉันแม้ว่ามันจะคุ้มค่าการพูดถึง
jfg956

1
นี่คือคำตอบที่ถูกต้อง การเปลี่ยนพฤติกรรมของเชลล์ไม่ใช่
EnzoR

หากตั้งค่าโลแคลไว้ถูกต้องคุณควรใช้คลาสที่เทียบเท่า[[=e=][=E=]]ได้
Benjamin W.

8

คุณยังสามารถเพิ่ม-iตัวเลือก (--ignore-case) grepเพื่อรับและเอาท์พุทด้านล่าง

[root@localhost ~]# ls -l | grep -i abc
-rw-r--r--  1 root root    0 Feb 25 20:41 fileabc.txt
-rw-r--r--  1 root root    0 Feb 25 20:41 fileABC.txt

การจับคู่รูปแบบมีประสิทธิภาพที่ดีกว่าเมื่อเทียบกับ grep เนื่องจาก grep ต้องการรวบรวมทุกอย่างแล้วจึงกรอง มีความแตกต่างที่เห็นได้ชัดเจนเมื่อทำงานกับโฟลเดอร์ที่ใหญ่กว่า
Omi

@Omi นอกจากนี้นิพจน์ทั่วไปใช้สำหรับข้อความโดยเฉพาะบรรทัดข้อความ ชื่อไฟล์อาจมีการขึ้นบรรทัดใหม่
Kusalananda

3

ฉันไม่คิดว่ามันเป็นไปได้สำหรับ ls แต่คุณสามารถใช้ find แทน:

find . -maxdepth 1 -iname '*abc*'

0

ใช้รหัสต่อไปนี้:

LC_COLLATE=en_US ; export LC_COLLATE
ls *abc*
LC_COLLATE=C ; export LC_COLLATE

ตัวแปร LC_COLLATE คืออะไร คุณช่วยอธิบายเพิ่มเติมได้ไหม
mtk

คลิกที่ลิงค์เพื่อทราบเกี่ยวกับ @mtk นี้
user1678213

0

คุณสามารถ grep ไฟล์โดยใช้-iซึ่งเพิ่มตัวเลือกที่ไม่รู้สึก

ตัวอย่างเช่นการค้นหาทั้งสองabcและABCคุณสามารถเรียกใช้คำสั่งนี้

    [root@mtk bin]# ls -l | grep -i abc
    640K -rw-r--r-- 1 mtk mtk 639K Sep 21 08:12 file1abc.txt
    676K -rw-r--r-- 1 mtk mtk 674K Sep 21 08:12 file2ABC.txt

5
Luis Perez ฉันคิดว่าคุณไม่ได้ใช้-iตัวเลือกในการสั่งการ
Mongrel


-2

ใน tcsh ตั้งค่านามแฝงเป็น .aliases

alias lsnc "ls BS!* | sort -f "

("BS" = หนึ่ง "backslash"; ฉันต้องใช้สิ่งนี้เพื่อให้มันปรากฏในเบราว์เซอร์ของฉัน)

และใช้lsncแทนls

ในทุบตีลองนามแฝงใน. bash_aliases เช่น

lsnc() { ls $1 | sort -f ; }

ด้วยตัวเลือกต่างๆlsเช่นls -lนี่คือการแก้ไขอย่างง่าย:

tcsh:

alias lsncl "ls -l BS!* | sort -f -k 9"

ทุบตี:

lsncl() { ls -l $1 | sort -f -k 9 ; }

คุณแน่ใจหรือไม่ว่าคุณไม่ได้หายไป=หลังจาก 'lsnocase'
Anthon

Anthon: lsnc (ปรับปรุง) และ lsncl ทำงานได้ดีสำหรับฉันภายใต้ tcsh และ bash ทั้งบน Cygwin และ Ubuntu โปรดทราบว่าสำหรับทุบตีฉันกำลังใช้ฟังก์ชั่นไม่ใช่ "นามแฝง" ต่อ se Lester
Lester Ingber

Anthon: ใช่คุณน่าจะใช้นามแฝงเป็น bash ได้เช่น alias lsncl = 'ls -l $ 1 | sort -f -k 9 '
Lester Ingber

คำตอบนี้ไม่ได้ตอบคำถามเฉพาะที่ต้องการส่งไฟล์ที่ส่งไปยัง ls เพื่อให้ถือว่าเป็นกรณี ๆ ไป หากเชลล์ส่งผ่านไฟล์จำนวนน้อยเกินไปให้lsไม่มีสิ่งใดlsและsortสามารถแก้ไขสถานการณ์ได้ ดังที่ระบุไว้ในคำตอบอื่น ๆ ปัญหาจำเป็นต้องแก้ไขในเชลล์ไม่ใช่ด้วยlsไวยากรณ์
Mark Stosberg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.