Como combinar padrões sem distinção entre maiúsculas e minúsculas com ls?

57

Gostaria de listar todos os arquivos que correspondam a um determinado padrão e ignorar o caso.

Por exemplo, eu executo os seguintes comandos:

ls *abc*

Quero ver todos os arquivos que possuem "abc" como parte do nome do arquivo, ignorando o caso, como

-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

Nota

Eu procurei na página de manual por case, mas não encontrei nada.

mtk
fonte

Respostas:

65

Isso é realmente feito pelo seu shell, não por ls.

Em bash, você usaria:

shopt -s nocaseglob

e, em seguida, execute seu comando.

Ou em zsh:

unsetopt CASE_GLOB

Ou em yash:

set +o case-glob

e então o seu comando.

Você pode colocar isso em .bashrc, .zshrcou .yashrc, respectivamente.

Como alternativa, com zsh:

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

(isto é, globbing sem diferenciação de maiúsculas e minúsculas por curinga)

Com ksh93:

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

Você deseja que o globbing funcione de maneira diferente, lspois esses são todos os arquivos transmitidos lspelo shell.

polemon
fonte
No bash, como redefinir a configuração original, se eu usar shport -s nocaseglob?
mtk
6
@mtk: Para definir uma opção, você usa shopt -s; para desabilitar , você usa shopt -u. Alternativamente, você pode embrulhar tudo em um subshell usando ( )para que a configuração não afeta o shell pai: (shopt -s nocaseglob ; ls *abc*).
ruakh 21/09/12
Portanto, não há maneiras portáteis para isso no POSIX ou SUS ou algo parecido (exceto [aA][bB][cC])?
Timothy Gu
Excelente solução, não acredito que não encontrei o shoptcomando nos últimos 15 anos de uso do bash!
Reza Sanaie 28/05
A resposta de Jfg956 é a correta (a próxima). Por que mudar o comportamento do shell quando você tem uma regexp para isso?
EnzoR 13/11
20

Conforme explicado pelo polemon, é o shell (não o ls) que se estende *abc*a uma lista de arquivos. Isso é chamado de correspondência de padrões .

Além de alterar todo o comportamento da correspondência de padrões para ignorar maiúsculas e minúsculas, você pode usar outra forma de correspondência de padrões que não a *. O seguinte faria o que você deseja no bash:

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

Do bash man:

[...] Corresponde a qualquer um dos caracteres incluídos.

Isso permite uma correspondência de grão mais fino, onde você pode usar *[aA][bB]c*para combinar abcou ABcmas não abCou ABC. Ou um exemplo em francês, onde eu poderia querer corresponder a todas as instâncias do epersonagem:

ls *[eéèêëEÉÈÊË]*
jfg956
fonte
11
Infelizmente, essa abordagem rapidamente se torna difícil à medida que o padrão aumenta. Mas para coisas curtas, funciona.
Derobert 21/09/12
@derobert: totalmente verdadeiro, especialmente é (e provavelmente é o caso) que o shell otimizou o caso de ignição correspondente colocando todos os nomes de arquivos e a solicitação de correspondência em letras minúsculas antes de comparar. No entanto, o [...]pode ser útil em muitos casos, e eu pensei que valia a pena mencionar.
Jfg956 22/09/12
11
Esta é a resposta certa. Alterar o comportamento do shell não é.
EnzoR 13/11/19
Se o código do idioma estiver definido corretamente, você poderá usar classes de equivalência [[=e=][=E=]].
Benjamin W.
8

Você também pode adicionar a -iopção (--ignore-case) greppara obter e a saída abaixo.

[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
Mongrel
fonte
A correspondência de padrões tem um desempenho melhor em comparação com o grep porque o grep precisa reunir tudo e depois filtrar. Tem uma diferença notável ao trabalhar com pastas maiores.
Omi
@Omi Além disso, expressões regulares são para texto , especificamente linhas de texto. Os nomes de arquivos podem conter novas linhas.
Kusalananda
3

Eu não acho que isso seja possível com ls, mas você poderia usar o find:

find . -maxdepth 1 -iname '*abc*'
esteira
fonte
0

use o seguinte código:

LC_COLLATE=en_US ; export LC_COLLATE
ls *abc*
LC_COLLATE=C ; export LC_COLLATE
user1678213
fonte
Para que serve a variável LC_COLLATE? você pode explicar mais?
mtk
clique no link de saber sobre este @mtk
user1678213
0

Você pode fazer o GREP do arquivo usando o -ique adiciona a opção insensível.

Por exemplo, para encontrar os dois abce ABCvocê pode executar este comando

    [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
Luis Perez
fonte
5
Luis Perez Acho que você não usou a -iopção em nenhum lugar do seu comando.
Mongrel
-2

No tcsh, defina um alias em .aliases

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

("BS" = uma "barra invertida"; eu tive que usar isso para aparecer no meu navegador.)

e use em lsncvez dels

No bash, tente um alias em .bash_aliases como

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

Com opções para ls, por exemplo ls -l, aqui está uma correção simples:

tcsh:

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

bater:

lsncl() { ls -l $1 | sort -f -k 9 ; }
Lester Ingber
fonte
Tem certeza de que não está faltando um ' =' após o lsnocase?
Anthon
Anthon: O (revisado) lsnc e lsncl funcionam para mim sob tcsh e bash no Cygwin e no Ubuntu. Observe que, para o bash, estou usando uma função, não um "alias" em si. Lester
Lester Ingber
Anthon: Sim, você provavelmente pode usar o alias no bash, como o alias lsncl = 'ls -l $ 1 | tipo -f k 9'
Lester Ingber
Esta resposta não aborda a pergunta específica que deseja passar os arquivos passados ​​para ls para serem tratados como distinção entre maiúsculas e minúsculas. Se o shell passar passar poucos arquivos para ls, não há nada lse sortpossa consertar a situação. Conforme observado em outras respostas, o problema precisa ser resolvido no shell, não com uma lssintaxe.
Mark Stosberg