Làm thế nào để khớp mẫu không nhạy cảm với ls?


57

Tôi muốn liệt kê tất cả các tệp khớp với một mẫu nhất định trong khi bỏ qua trường hợp.

Ví dụ, tôi chạy các lệnh sau:

ls *abc*

Tôi muốn xem tất cả các tệp có "abc" là một phần của tên tệp, bỏ qua trường hợp, như

-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

Ghi chú

Tôi đã tìm kiếm trang người đàn ông cho trường hợp, nhưng không thể tìm thấy bất cứ điều gì.

Câu trả lời:


65

Điều này thực sự được thực hiện bởi vỏ của bạn, không phải bởi ls.

Trong bash, bạn sẽ sử dụng:

shopt -s nocaseglob

sau đó chạy lệnh của bạn.

Hoặc trong zsh:

unsetopt CASE_GLOB

Hoặc trong yash:

set +o case-glob

và sau đó là lệnh của bạn.

Bạn có thể muốn đặt nó vào .bashrc, .zshrchoặc .yashrc, tương ứng.

Ngoài ra, với zsh:

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

(đó là trường hợp toàn cầu hóa không nhạy cảm trên cơ sở mỗi ký tự đại diện)

Với ksh93:

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

Bạn muốn globalbing hoạt động khác nhau, không phải ls, vì đó là tất cả các tệp được truyền lsbởi shell.


Trong bash, làm thế nào để thiết lập lại cài đặt gốc, Nếu tôi sử dụng shport -s nocaseglob?
mtk

6
@mtk: Để đặt tùy chọn, bạn sử dụng shopt -s; để bỏ đặt nó, bạn sử dụng shopt -u. Ngoài ra, bạn có thể bọc mọi thứ trong một khung con bằng cách sử dụng ( )để cài đặt không ảnh hưởng đến vỏ cha : (shopt -s nocaseglob ; ls *abc*).
ruakh

Vì vậy, không có cách di động nào cho điều này trong POSIX hoặc SUS hoặc một cái gì đó tương tự (ngoại trừ [aA][bB][cC])?
Timothy Gu

Giải pháp tuyệt vời, tôi không thể tin rằng mình đã không gặp phải shoptlệnh trong 15 năm qua sử dụng bash!
Reza Sanaie

Câu trả lời của Jfg956 là câu trả lời đúng (tiếp theo). Tại sao thay đổi hành vi shell khi bạn có một biểu thức chính quy cho điều đó?
EnzoR

20

Như được giải thích bởi polemon, nó là shell (không phải ls) mở rộng *abc*đến một danh sách các tập tin. Đây được gọi là Kết hợp mẫu .

Ngoài việc thay đổi toàn bộ hành vi Khớp mẫu để bỏ qua trường hợp, bạn có thể sử dụng một hình thức khớp mẫu khác so với *. Sau đây sẽ làm những gì bạn muốn trong bash:

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

Từ bash man:

[...] Khớp với bất kỳ một trong các ký tự kèm theo.

Điều này cho phép kết hợp hạt mịn hơn nơi bạn có thể sử dụng *[aA][bB]c*để khớp abchoặc ABckhông abChoặc ABC. Hoặc một ví dụ bằng tiếng Pháp, nơi tôi có thể muốn khớp tất cả các phiên bản của enhân vật:

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

1
Thật không may, cách tiếp cận đó nhanh chóng trở nên khó sử dụng khi mô hình trở nên dài hơn. Nhưng đối với những điều ngắn, nó hoạt động.
derobert

@derobert: hoàn toàn đúng, đặc biệt là (và có lẽ là như vậy) shell đã tối ưu hóa trường hợp bỏ qua khớp bằng cách đặt tất cả tên tệp và yêu cầu khớp trong trường hợp thấp hơn trước khi so sánh. Tuy nhiên, nó [...]có thể hữu ích trong nhiều trường hợp, và tôi mặc dù nó đáng được đề cập.
jfg956

1
Đây là câu trả lời đúng. Thay đổi hành vi vỏ là không.
EnzoR

Nếu miền địa phương được đặt đúng, bạn sẽ có thể sử dụng các lớp tương đương [[=e=][=E=]].
Benjamin W.

8

Bạn cũng có thể thêm -itùy chọn (--ignore-case) grepđể nhận và đầu ra bên dưới.

[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

Kết hợp mẫu có hiệu suất tốt hơn so với grep vì grep cần thu thập mọi thứ và sau đó lọc. Có một sự khác biệt đáng chú ý khi làm việc với thư mục lớn hơn.
Omi

@Omi Ngoài ra, các biểu thức thông thường dành cho văn bản , cụ thể là các dòng văn bản. Tên tệp có thể chứa dòng mới.
Kusalananda

3

Tôi không nghĩ rằng điều này là có thể với ls, nhưng bạn có thể sử dụng find thay thế:

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

0

sử dụng mã sau đây:

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

Biến LC_COLLATE để làm gì? bạn có thể giải thích thêm
mtk

nhấp vào liên kết để biết về điều này @mtk
user1678213

0

Bạn có thể GREP tệp bằng cách -ithêm tùy chọn không nhạy cảm.

Ví dụ để tìm cả hai abcABCbạn có thể chạy lệnh này

    [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 Tôi nghĩ rằng bạn đã không sử dụng -itùy chọn bất cứ nơi nào trong lệnh của bạn.
Mongrel


-2

Trong tcsh, đặt bí danh trong .aliases

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

("BS" = một "dấu gạch chéo ngược"; tôi đã phải sử dụng điều này để khiến nó hiển thị trong trình duyệt của mình.)

và sử dụng lsncthay vìls

Trong bash, hãy thử một bí danh trong .bash_aliases như

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

Với các tùy chọn ls, ví dụ ls -l, đây là một sửa chữa đơn giản:

tcsh:

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

bash

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

Bạn có chắc là bạn không thiếu ' =' sau lsnocase không?
Anthon

Anthon: lsnc và lsncl (đã được sửa đổi) hoạt động với tôi theo tcsh và bash trên cả Cygwin và Ubuntu. Lưu ý rằng đối với bash, tôi đang sử dụng một hàm, không phải là "bí danh" mỗi lần. Lester
Lester Ingber

Anthon: Có, bạn có thể sử dụng bí danh trong bash, như bí danh lsncl = 'ls -l $ 1 | sort -f -k 9 '
Lester Ingber

Câu trả lời này không giải quyết câu hỏi cụ thể muốn chuyển các tệp được chuyển đến ls để được coi là không phân biệt chữ hoa chữ thường. Nếu shell chuyển quá ít tệp đến ls, không có gì lssortcó thể khắc phục tình huống. Như đã lưu ý trong các câu trả lời khác, vấn đề cần được giải quyết trong shell chứ không phải bằng một lscú pháp.
Mark Stosberg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.