Come abbinare modelli insensibili alle maiuscole e minuscole con ls?


58

Vorrei elencare tutti i file corrispondenti a un determinato modello ignorando il caso.

Ad esempio, eseguo i seguenti comandi:

ls *abc*

Voglio vedere tutti i file che hanno "abc" come parte del nome del file, ignorando il caso, come

-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

Ho cercato caso nella pagina man, ma non sono riuscito a trovare nulla.

Risposte:


65

Questo è effettivamente fatto dalla tua shell, non da ls.

In bash, useresti:

shopt -s nocaseglob

e quindi esegui il tuo comando.

O in zsh:

unsetopt CASE_GLOB

O in yash:

set +o case-glob

e poi il tuo comando.

Potresti volerlo inserire in .bashrc, .zshrco .yashrc, rispettivamente.

In alternativa, con zsh:

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

(ovvero globbing insensibile al maiuscolo / minuscolo in base al carattere jolly)

Con ksh93:

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

Volete che il globbing funzioni in modo diverso, lspoiché questi sono tutti i file trasmessi lsdalla shell.


In bash, come ripristinare l'impostazione originale, se uso shport -s nocaseglob?
— mtk,

6
@mtk: per impostare un'opzione, si utilizza shopt -s; per disinserirlo , usi shopt -u. In alternativa, si può avvolgere tutto in una subshell utilizzando ( )in modo che l'impostazione non influisce sulla shell genitore: (shopt -s nocaseglob ; ls *abc*).
— Ruakh,

Quindi non ci sono modi portatili per questo in POSIX o SUS o qualcosa del genere (eccetto [aA][bB][cC])?
— Timothy Gu,

Ottima soluzione, non posso credere di non essermi imbattuto nel shoptcomando negli ultimi 15 anni di utilizzo di bash!
— Reza Sanaie,

La risposta di Jfg956 è quella giusta (la prossima). Perché cambiare il comportamento della shell quando hai una regexp per questo?
— EnzoR,

20

Come spiegato da polemon, è la shell (non ls) che si estende *abc*a un elenco di file. Questo si chiama Pattern Matching .

Oltre a modificare l'intero comportamento di Pattern Matching per ignorare il caso, è possibile utilizzare un'altra forma di pattern matching rispetto a *. Quanto segue farebbe quello che vuoi in bash:

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

Da bash man:

[...] Corrisponde a uno qualsiasi dei caratteri racchiusi.

Ciò consente una corrispondenza più fine della grana dove è possibile utilizzare la *[aA][bB]c*corrispondenza abco ABcmeno abCoppure ABC. O un esempio in francese, dove potrei voler abbinare tutte le istanze del epersonaggio:

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

1
Sfortunatamente, tale approccio diventa rapidamente ingombrante man mano che il modello si allunga. Ma per farla breve, funziona.
— derobert,

@derobert: assolutamente vero, soprattutto è (ed è probabilmente il caso) la shell ha ottimizzato la corrispondenza ignorando il caso mettendo tutti i nomi di file e la richiesta di corrispondenza in lettere minuscole prima del confronto. Tuttavia, [...]può essere utile in molti casi e ho pensato che valesse la pena menzionarlo.
— jfg956,

1
Questa è la risposta esatta. Cambiare il comportamento della shell non lo è.
— EnzoR,

Se le impostazioni internazionali sono impostate correttamente, dovresti essere in grado di utilizzare le classi di equivalenza [[=e=][=E=]].
— Benjamin W.,

8

Puoi anche aggiungere l' -iopzione (--ignore-case) grepper ottenere e l'output di seguito.

[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

La corrispondenza dei modelli ha prestazioni migliori rispetto a grep perché grep deve raccogliere tutto e quindi filtrare. Ha una notevole differenza quando si lavora con una cartella più grande.
— Omi,

@Omi Inoltre, le espressioni regolari sono per il testo , in particolare le righe di testo. I nomi dei file possono contenere righe.
— Kusalananda

3

Non penso che questo sia possibile con ls, ma potresti usare find invece:

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

0

usa il seguente codice:

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

A cosa serve la variabile LC_COLLATE? puoi spiegare ulteriormente.
— mtk

fai clic sul link per conoscere questo @mtk
— user1678213

0

È possibile GREP il file utilizzando il -iquale aggiunge l'opzione insensibile.

Ad esempio per trovare entrambi abced ABCè possibile eseguire questo 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 Penso che tu non abbia usato l' -iopzione da nessuna parte nel tuo comando.
— Ibrido


-2

In tcsh, imposta un alias in .alias

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

("BS" = one "backslash"; ho dovuto usare questo per farlo apparire nel mio browser.)

e usa lsncinvece dils

In bash, prova un alias in .bash_aliases come

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

Con le opzioni ls, ad esempio ls -l, ecco una semplice soluzione:

tcsh:

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

bash:

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

Sei sicuro di non perdere un ' =' dopo lsnocase?
— Anthon,

Anthon: lsnc e lsncl (rivisto) funzionano per me sotto tcsh e bash su Cygwin e Ubuntu. Nota che per bash sto usando una funzione, non un "alias" di per sé. Lester
— Lester Ingber,

Anthon: Sì, probabilmente puoi usare l'alias in bash, come alias lsncl = 'ls -l $ 1 | sort -f -k 9 '
— Lester Ingber

Questa risposta non affronta la domanda specifica che vuole passare i file passati a LS per essere trattati senza distinzione tra maiuscole e minuscole. Se la shell passa passa troppo pochi file a ls, non c'è niente lse sortpossibile per risolvere la situazione. Come notato in altre risposte, il problema deve essere risolto nella shell, non con una lssintassi.
— Mark Stosberg,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.