Bash: ls * senza raggruppamento di cartelle


12

Se scrivo:

ls source/*

source/fonts:
fontello

source/images:
bg1.png                eng.png        fra.png   

Ottengo l'elenco dei file, raggruppati per nomi di cartelle. Come posso semplicemente ottenere l'elenco dei nomi dei file?

ls source/*

source/fonts/fontello
source/images/bg1.png
source/images/eng.png
source/images/fra.png   

Grazie


Se questo è per l'uso degli script, potresti voler vedere mywiki.wooledge.org/ParsingLs . (Detto questo, ci sono anche modi di usare findqualcosa di sbagliato; in particolare, se stai correndo for file in $(find ...), ne hai colpito uno).
Charles Duffy,

Risposte:


13

Non sembra possibile senza alterazione dell'output, ma qui è un modo semplice alternativo:

find source/ -type f

Oppure (specifico di GNU find), per ottenere solo i file in modo approfondito nella tua domanda:

find source/ -type f -mindepth 2 -maxdepth 2

(o se vuoi directory come lsti dà, rimuovi -type f)


5

Puoi semplicemente attenerti a ls se aggiungi alcuni psichedlics ( ls -d):

# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*    
A/file  B/file  C/file

@Cthulhu ok il mio esempio è troppo breve, se hai cartelle in A, B a / o C il -d aiuta a visualizzare solo ciò che hai selezionato. In realtà non mi piace trovare e puoi definire la profondità dall'argomento con ls -d
ikrabbe,

Ho suggerito una modifica all'altra risposta per limitare la profondità.
o11c,

@ o11c molto bene, ma findè ancora una bestia grassa.
Ikrabbe,

3

Potresti essere interessato a "il povero find":

shopt -s globstar

shopt -s s Ets l'opzione di shell di nome (s). L' globstaropzione è definita come segue in bash (1) :

Se impostato, il modello **utilizzato in un contesto di espansione nome file / percorso corrisponderà a un file [sic] e zero o più directory e sottodirectory. Se il modello è seguito da a /, corrispondono solo le directory e le sottodirectory.

Quindi, dopo aver completato shopt -s globstar, uno dei seguenti comandi:

ls -d1 - source / **                  # Il carattere dopo la 'd' è quello della cifra. 
ls -d - source / ** | cat             # ie, lo scriverà in una pipe a qualsiasi comando. 
printf "% s \ n" source / **

produrrà l'output:

source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png

Sfortunatamente, questo include anche i nomi delle directory. Potrebbe aiutarti un po ' a saperlo

printf "%s\n" source/**/

produrrà l'output:

source/
source/fonts
source/images

cioè, solo i nomi delle directory. Si potrebbe reindirizzare l'output di uno dei prima serie di comandi a un file, reindirizzare l'output di cui sopra ad un secondo file, e quindi utilizzare comm, diffo qualcosa di simile, per sottrarre il secondo file dal primo, lasciando solo la pianura file (non directory). Ma non farlo.

Un altro approccio (che non è molto meglio) è

ls -d --file-type -- source/** | grep -v '/$'

L' --file-typeopzione dice lsdi visualizzare / a alla fine di ogni nome di directory (e altri caratteri alla fine di altri tipi di file (speciali)), in questo modo:

fonte //                             # Aggiunta di una 
fonte / caratteri /                        # aggiunta
source / fonts / fontello
fonte / immagini /                       # aggiunto uno
source / images / bg1.png
source / images / eng.png
source / images / fra.png

e quindi grep -v '/$'rimuove le linee che finiscono con /; cioè i nomi delle directory. Sfortunatamente, l' --file-typeopzione non è specificata da POSIX . Se la tua versione di lsnon lo supporta, usa -F. È come --file-type se tranne che mostra anche una *alla fine dei nomi dei file eseguibili, che alcune persone trovano fastidiose. Puoi eliminarli con sed:

ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'

Se vuoi fare qualcosa con tutti i file (e solo i file), puoi farlo

per f in sorgente / **
fare
    if [-f "$ f"]
    poi
        Inserisci qui i comandi da applicare ai file semplici.
    fi
fatto

Appunti:

  • Quando lsviene inviato a un terminale e non è in modalità -l( l ong), scrive più nomi per riga (a meno che i nomi non siano molto lunghi). È possibile forzarlo a scrivere un nome per riga specificando -1(uno) o reindirizzando l'output su un file o una pipe.
  • Probabilmente non si ha realmente bisogno l' --nei lscomandi dal momento che stai elencando una directory il cui contenuto è stato creato. Dovresti usarlo quando ti elenchi *in una directory sconosciuta, come protezione contro i nomi di file che iniziano con -.
  • Non tentare di analizzare l'output da ls.
  • L' globstaropzione shell sembra non essere definita da POSIX. (In realtà, io non sono sicuro POSIX riconosce eventuali opzioni di shell.) Mentre sembra essere un bashismo, attenzione - potrebbe non essere presente in tutte le versioni di bash.
  • Se fontso imagesha delle sottodirectory, **le elencherà tutte, ricorsivamente, fino in fondo. Un modo (alquanto kludgy e inaffidabile) per limitare la profondità è

    ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
    

    che rimuove le righe contenenti tre o più /caratteri.

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.