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.

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.


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ÉÈÊË]*

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

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*'

0

use o seguinte código:

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

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

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 ; }

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.