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
ls
sta 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
--
nells
commands 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
globstar
l'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 unbash
ism, attenzione:potrebbe non essere presente in tutte le versioni di bash. -
Se
fonts
oimages
ha 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.