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.