Non sembra essere possibile senza l'alterazione dell'output, ma ecco un semplice modo alternativo:
find source/ -type f
Oppure (specifico per GNU find), per ottenere solo i file in profondità nella tua domanda:
find source/ -type f -mindepth 2 -maxdepth 2
(o se vuoi directory come ls ti dà, rimuovi -type f )
Puoi semplicemente attenerti a ls se aggiungi alcuni psichedelici (ls -d ):
# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*
A/file B/file C/file
Potresti essere interessato a “il find del povero ”:
shopt -s globstar
shopt -s s imposta le opzioni di shell denominate. Il globstar option è definita come segue in bash(1):
Se impostato, il pattern
**utilizzato in un contesto di espansione di nome file/percorso corrisponderà a un file [sic] ezero o più directory e sottodirectory. Se lo schema è seguito da un/, solo le directory e le sottodirectory corrispondono.
Quindi, dopo aver eseguito shopt -s globstar , uno dei seguenti comandi:
ls -d1 -- source/** # The character after the ‘d’ is the digit one. ls -d -- source/** | cat # i.e., it will write that into a pipe to any command. 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' saperlo
printf "%s\n" source/**/
produrrà l'output:
source/
source/fonts
source/images
cioè, solo i nomi delle directory. Potresti reindirizzare l'output di uno dei primi set di comandi a un file, reindirizzare l'output di quanto sopra a un secondo file e quindi utilizzare comm , diff , o qualcosa di simile, per sottrarre il secondo file dal primo, lasciando solo i file semplici (non directory). Ma non farlo.
Un altro approccio (non è molto meglio) è
ls -d --file-type -- source/** | grep -v '/$'
Il --file-type opzione indica ls per visualizzare un / alla fine di ogni nome di directory (e altri caratteri alla fine di altri tipi di file (speciali), in questo modo:
source// # Added an extra one source/fonts/ # Added one source/fonts/fontello source/images/ # Added one source/images/bg1.png source/images/eng.png source/images/fra.png
e poi il grep -v '/$' rimuove le righe che terminano con /;cioè, i nomi delle directory. Sfortunatamente, il --file-type l'opzione non è specificata da POSIX. Se la tua versione di ls non lo supporta, usa -F . È come --file-type tranne che mostra anche un * alla fine dei nomi dei file eseguibili, che alcune persone trovano fastidioso. Puoi eliminarli con sed :
ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'
Se vuoi fare qualcosa con tutti i file (e solo con i file), puoi farlo
for f in source/**
do
if [ -f "$f" ]
then
Insert commands to be applied to plain files here.
fi
done Note:
- Quando
lssta emettendo su un terminale e non è in-l(l ong), scrive più nomi per riga (a meno che i nomi non siano molto lunghi). Puoi forzarlo a scrivere un nome per riga specificando-1(uno), o reindirizzando l'output a un file oa una pipe. - Probabilmente non hai davvero bisogno del
--nellscommands poiché stai elencando una directory di cui hai creato i contenuti. Dovresti usarlo quando elenchi*in una directory sconosciuta, come protezione contro i nomi di file che iniziano con-. - Non tentare di analizzare l'output da
ls. - Il
globstarl'opzione shell sembra non essere definita da POSIX. (In effetti, non sono sicuro che POSIX ne riconosca qualsiasi opzioni della shell.) Anche se sembra essere unbashism, attenzione:potrebbe non essere presente in tutte le versioni di bash. -
Se
fontsoimagesha sottodirectory,**li elencherà tutti, ricorsivamente, fino in fondo. Un modo (un po' goffo e inaffidabile) per limitare la profondità èls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'che rimuove le righe contenenti tre o più
/caratteri.