Come elencare i file senza directory e filtrare per nome (opzioni ls)


42

Ho una directory chiamata uploads. Contiene un mucchio di file, oltre ad alcune sottodirectory che a loro volta contengono file.

C'è un modo in cui posso (in un solo passaggio) fare quanto segue:

  1. Elencare SOLO i file nella directory dei caricamenti di root - Non voglio vedere i nomi delle sottocartelle o il loro contenuto;

    e

  2. NON elencare alcun file che inizia con t_

Conosco la -dbandiera, ma non mi dà proprio quello che voglio.

Risposte:


53

Sembra un lavoro per find.

  • Utilizzare -maxdepthper restituire solo la directory corrente, non ricorsivamente cercare all'interno delle sottocartelle
  • Utilizzare -type fper restituire solo file e non directory o nodi del dispositivo o qualsiasi altra cosa
  • Utilizzare una combinazione se -note -nameper evitare i file con nomi che non si desidera

Potrebbe unirsi così:

find /path/to/uploads -maxdepth 1 -type f -not -name 't_*'

Grazie! Sono abbastanza nuovo per CLI e non avevo mai usato find prima. Sicuramente approfondirò ulteriormente.
EmmyS

2
@EmmyS: potresti trovare un altro piccolo trucco utile qui. @Gilles menzionato usando -exec ls -lG -- {} +nella sua risposta per ottenere l'output usando opzioni extra per ls. Puoi anche aggiungere solo una -lsa questa scoperta per ottenere un'approssimazione veloce e sporca della vista dettagliata di ls.
Caleb,

18

GNU ls (ovvero il comando ls su sistemi Linux non embedded e Cygwin, disponibile anche su alcuni altri unices) ha un'opzione per nascondere alcuni file, in base al loro nome. Non c'è modo di ignorare le directory però.

ls --hide='t_*' uploads

Un altro approccio è fare in modo che la shell esegua la corrispondenza. Bash, ksh e zsh hanno un modello di negazione !(t_*)per abbinare tutti i file tranne quelli corrispondenti t*; in bash questa funzione deve essere attivata con shopt -s extglob, e in zsh deve essere attivata con setopt ksh_glob. Zsh ha anche la sintassi equivalente ^t_*che deve essere attivata setopt extended_glob. Questo non ignora ancora le directory. Zsh ha una funzione extra che permette di abbinare i file non solo per nome ma anche per metadati e altro: qualificatori glob . Aggiungi (.)alla fine di una partita per limitare ai file normali. La negazione ^fa parte della sintassi di corrispondenza del nome, quindi ^t_*(.)significa "tutti i file normali non corrispondenti t_*" e non "tutti i file che non corrispondono regolarmente t_*".

setopt extended_glob  # put this in your ~/.zshrc
ls uploads/^t_*(.)

Se ti trovi senza strumenti avanzati, puoi farlo su qualsiasi unix con find. Non è il tipo di cosa che digiti in genere sulla riga di comando, ma è potente e preciso. Caleb ha già mostrato come farlo con GNU find . L' -maxdepthopzione non è portatile; puoi -pruneinvece utilizzare , per interrompere findin modo portabile il ripetersi.

find uploads/* -type d -prune -o \! -type f -name 't_*' -print

Sostituisci -printcon -exec ls -lG -- {} +per eseguire lscon le tue opzioni preferite sui file.

Tutti i comandi sopra nascondono i file punto (cioè i file il cui nome inizia con a .). Se si desidera visualizzarli, passare -Aa lso aggiungere il Dqualificatore glob in zsh ( ls uploads/^t_*(.D)). Con find, è possibile utilizzare un approccio diverso per farlo ricorrere a un solo livello ( findnon tratta i file di punti in particolare). Funziona completamente solo se eseguito findnella directory corrente.

cd uploads && find . -name . -o -type d -prune -o \! -type f -name 't_*' -print

3
Hai una sega? ;-) Sono costantemente sorpreso dalla lunghezza e dal livello dei dettagli delle tue risposte, anche alle domande più semplici qui su Unix SE! .. Continuate così comunque! :)
alex

Grazie! Grande dettaglio. Non so se ho "strumenti avanzati" o no in questo momento; Sono su un Mac al lavoro (anche se Linux a casa, quindi sono sicuro che questo tornerà utile a un certo punto.)
EmmyS

@EmmyS: Per il tuo Linux box il mio uso -maxdepthdovrebbe funzionare, ma il problema della "portabilità" a cui Gilles fa riferimento è che il BSD find(anch'esso trovato su OSX credo) sia un po 'diverso, quindi potresti aver bisogno anche della sua risposta. @Gilles: +1 per il trucco zsh!
Caleb,

1
@Gilles: Mi prunevengono in mente alcuni commenti non così succosi su s, ma lo lascerò andare semplicemente dicendo che quando mi metto in giro sui miei sistemi il numero di volte in cui il pensiero "funzionerebbe questo comando se fossi attivo AIX, Solaris o MINIX3 "è approssimativamente ... standby ... Sto facendo fatica a leggere un contatore ... il display è bloccato 0.00.
Caleb,

2
Gnu non lsha --use-telepathyun'opzione? Questo è il modo più veloce per visualizzare solo i file desiderati. Potrebbe non essere portatile però.
dubiousjim,

8
ls -l /folder | grep ^- | awk '{print $9}'

Cosa c'è $9in questa affermazione?
EmmyS,

3
@EmmyS Indica il nono campo / colonna dell'output. Questa risposta sta cercando di analizzare l' lsoutput .
jw013,

print $ NF` sarebbe meglio, IMO. $ NF indica il numero di campi, che sarebbe 9 ed è un uso comune in AWK come buona opportunità per insegnare agli altri $ NF.
Elijah Lynn,

1
ls -l | grep -v ^d | grep name$

Cosa renderebbe preferibile questa soluzione (che richiede più comandi e pipe) find?
HalosGhost

È conciso, facile da leggere e rimane con la convenzione di comando ls. Trovo più facile da ricordare degli argomenti del comando find. A ciascuno il proprio e complimenti per le opzioni!
tkjef,

0

Lasciami fare un tentativo usando lse pipe:

ls  -l --hide='t_*'  uploads/ | grep -v ^d | tr -s ' ' | cut -d ' ' -f 9

dire che l'ultima colonna è la nona.


1
Cosa succede se ci sono file con spazi?
jordanm,

0

Se il problema di portabilità di max -epth di find è un problema, puoi usare:

ls -l uploads/ | awk '/^-/ && $9 !~/^t_/ {print $9}'

Non sono un esperto, ma penso che dovrebbe funzionare. Suppongo che sia un po 'enigmatico, ma se parli male, in realtà non lo è. $ NF potrebbe essere utilizzato invece di $ 9. Puoi anche fare:

ls -l uploads/ | awk '/^-/' | awk '!/^t_/ {print $9}'

che fa la stessa cosa (ma forse in modo meno efficiente del precedente ???).

In realtà, dopo aver pensato agli altri post, sembra

ls -l --hide=t_* uploads/ | awk '/^-/ {print $9}'

è un modo ancora più breve e più chiaro.

Qualcuno, per favore, correggimi se sbaglio. :-)


L'analisi non lsè generalmente una buona idea . I tuoi trucchi awk falliranno con nomi di file con spazi bianchi ad esempio.
Mat

@mat - Grazie per la correzione. Dopo aver letto l'articolo che voi (e jw013) ha sottolineato, vedo che ls non può essere attendibile per i nomi dei file corretti uscita. Anche se dovessi riscrivere il codice awk per stampare tutto, dai $ 9 alla fine della linea (per includere spazi bianchi), questo ls uscita potrebbe essere ancora erronea. Questo è deludente e dovrebbe essere corretto IMO. Grazie ancora.
kkaszub,

0

Ho trovato questi modi brevi:

ls -p uploads | grep -Ev '/'

o

ls -pIt_* uploads | grep -v /

-1

Prova questo alias e usalo:

alias l='ls -hLlF'

ls -hLlFmostra le sottodirectory e mostra i file che iniziano con t_. Quindi, come risponde alla domanda?
Raphael Ahrens,

Forse ho frainteso la domanda. ls -hLlF non mostrerà le directory di destinazione delle directory collegate.
Granulare

Così sembra. Ma non hai letto le altre risposte alla domanda?
Raphael Ahrens,

-1

Vai tranquillo:

ls -l --hide 't_*' <absolute path to desired directory> | grep -v ^d


(1) Questa risposta è così semplice, è stata data prima. (2) Perché ritieni di dover specificare il percorso completo della directory?
Scott,

@Scott: questo è un modo molto rapido e semplice per arrivare alla soluzione. Il percorso completo è stato specificato per rendere la risposta universale ...
Digger
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.