Uso della sostituzione del nome file - Come cercare file con lettere in questo ordine?

2

Quindi ho bisogno di trovare tutti i file che hanno d, o, e g nel nome del file. Le lettere non devono essere affiancate (aadaaoaagaa sarebbe un nome di file corretto, aaoaadaag non sarebbe un nome di file corretto). Non importa se le lettere sono maiuscole o minuscole (aadaaOaag è un nome file corretto, come aaDoGa.

Come dovrei usare la sostituzione dei nomi dei file sulla riga di comando del terminale per elencare tutti i file come questo? Preferibilmente senza usare loop o qualcosa di troppo avanzato. Tutto quello che mi è stato presentato fino ad ora è il carattere di sostituzione del nome file (*,?, [])

    
posta John Stacen 28.09.2013 - 04:57

4 risposte

2

Per elencarli quando sei nella directory in cui si trovano quei file, puoi usare, come diceva Nykakin in questo commento il seguente comando:

ls *[dD]*[oO]*[gG]*

o, se vuoi che ogni file sia sulla sua stessa linea, puoi usare:

printf '%s\n' *[dD]*[oO]*[gG]*

o, usando grep:

ls | grep [dD].*[oO].*[gG]
    
risposta data Radu Rădeanu 28.09.2013 - 08:07
2

Se comprendo correttamente il tuo problema, vuoi tutti quei nomi di file con d , o e g , in ogni caso (superiore o inferiore). Radu Rădeanu ti ha dato una risposta che funziona per le lettere che si verificano nell'ordine d - o - g . Ad esempio aaGaaaoaaDaa non sarà trovato. Puoi modificare la sua soluzione usando le sei permutazioni possibili, ad esempio,

ls *[dD]*[oO]*[gG]* *[oO]*[gG]*[dD]* *[gG]*[dD]*[oO]* *[oO]*[dD]*[gG]* *[dD]*[gG]*[oO]* *[gG]*[oO]*[dD]*

(l'impostazione di shopt -s nullglob prima è una buona idea).

Questo diventa un po 'disordinato, quindi potresti voler usare anche shopt -s nocaseglob in modo che la corrispondenza venga eseguita senza riguardo al caso di caratteri alfabetici (citato dal Manuale di riferimento Bash ) come:

$ shopt -s nullglob nocaseglob
$ ls *d*o*g* *o*g*d* *g*d*o* *o*d*g* *d*g*o* *g*o*d*

Un'altra opzione è usare il comando trova come, per esempio,

$ find . -maxdepth 1 -iname '*d*' -iname '*o*' -iname '*g*' -type f

L'opzione -maxdepth 1 è di limitare alla directory corrente e non le sue sottodirectory e -type f per limitare la ricerca ai file regolari. Cambia queste opzioni in base alle tue esigenze. -iname è per una ricerca senza distinzione tra maiuscole e minuscole nel nome (utilizzando i modelli glob). Non dimenticare le virgolette!

Un vantaggio di trovare è che sarai in grado di% ro_de% roba se devi eseguire qualsiasi operazione su questi file, ad esempio rinominandoli o aggiungendo loro elementi, ecc. Un altro vantaggio è che se si dispone di un numero enorme di tali file, il globbing richiederà anni e potrebbe persino traboccare il numero massimo di argomenti consentiti. find andrà bene, qualunque sia il numero di file.

Spero che questo aiuti!

Modifica. Sembra che mi sia sfuggita la parte in questo ordine nel titolo. Hahaha. Bene, allora il comando trova sarebbe semplicemente:

$ find . -maxdepth 1 -iname '*d*o*g*' -type f

e la soluzione -exec / ls sarebbe:

$ shopt -s nullglob nocaseglob
$ ls *d*o*g*
$ printf '%s\n' *d*o*g*
    
risposta data gniourf_gniourf 28.09.2013 - 16:03
1

Vorrei usare Perl per questo:

perl -le 'print for grep {/\A[a-cefh-np-z]*d[a-fh-z]*o[a-z]*g[a-z.]*\Z/i} <*>'

Spiegazione

  • <*> è magico: restituisce il risultato del globbing del pattern * dalla directory corrente.
  • grep{} restituisce solo quegli elementi del glob che corrispondono ai criteri al suo interno.
  • print restituisce il risultato di grep un elemento per riga a causa dell'opzione -l .
  • L'unico criterio utilizzato per grep è che il nome del file è composto esattamente da:

    • qualsiasi numero di lettere nel set [a-cefh-np-z] (l'alfabeto meno o e g )
    • la lettera d
    • qualsiasi numero di lettere nel set [a-fh-z] (l'alfabeto meno g)
    • la lettera o
    • un numero qualsiasi di qualsiasi lettera
    • la lettera g .
    • un numero qualsiasi di lettere o un punto (per le estensioni).
  • Il criterio i viene applicato al criterio regex per garantire che la corrispondenza non abbia distinzione tra maiuscole e minuscole come richiesto nella domanda.

So che questo non è esattamente quello che hai chiesto, ma credo che i modelli di caratteri jolly di Bash siano troppo semplici per gestire questa attività.

    
risposta data Joseph R. 28.09.2013 - 23:42
0

Un altro modo di considerare il problema sarebbe quello di mantenere solo i nomi dei file per i quali una volta eliminato ogni carattere al di fuori di D, O o G, il risultato sarebbe esattamente DOG , maiuscolo / minuscolo.

Questo potrebbe essere fatto in shell con search-replace-test al posto dei caratteri jolly:

#!/bin/bash
shopt -s nocasematch 
shopt -s nullglob
for i in *
do
  if [[ ${i//[^dogDOG]/} == dog ]]; then 
    echo $i;
  fi;
done
    
risposta data Daniel Vérité 29.09.2013 - 04:12

Leggi altre domande sui tag