So che è possibile utilizzare il comando find per questo semplice lavoro. Ma ho ricevuto un incarico di non usare find o ls e fare il lavoro. Per favore aiuto ....Come elencare in modo ricorsivo le sottodirectory in bash senza utilizzare i comandi find o ls?
risposta
Il comando du
elencherà le sottodirectory in modo ricorsivo.
io non sono sicuro se vuote directory ottengono una menzione, anche se
vengono visualizzate per me utilizzando bash sul mio mac –
Prova utilizzando
tree -d
Perché ho ricevuto un -1? Commenta per favore. –
Non ti ho dato il -1, ma per me è ovvio il motivo per cui l'hai preso. Perché non dare come risposta 'alias bla ls; bla'? La domanda che è stata posta era di scrivere l'algoritmo, non trovare qualche * comando * che faccia la stessa cosa di 'ls' ma non sia chiamato' ls'. – vladr
@Vlad Romascanu: Oh ... ok, ma da "Ho ricevuto un incarico di non usare find o ls e fare il lavoro" ho capito che tutto era abbastanza buono, tranne find e ls ^^ –
come Mark Byers ha detto è possibile utilizzare echo *
per ottenere un elenco di tutti i file nella corrente directory.
Il comando test
o []
ha un opzione per verificare se un file è una directory.
Applicare la ricorsione e il gioco è fatto.
In alternativa a' echo', 'for' sarà glob , così OP può usare 'per file in *; fare ... ; done'. – outis
si può fare con solo il guscio
#!/bin/bash
recurse() {
for i in "$1"/*;do
if [ -d "$i" ];then
echo "dir: $i"
recurse "$i"
elif [ -f "$i" ]; then
echo "file: $i"
fi
done
}
recurse /path
Oppure, se sei bash 4,0
#!/bin/bash
shopt -s globstar
for file in /path/**
do
echo $file
done
perché non si sottovaluta anche quello con il comando albero? o quello con eco, anche queste sono risposte valide. – ghostdog74
Questo fallirà se una directory è vuota, cioè stamperà 'dir: bla/*' poiché 'bla/*' è visto come un letterale in quanto non ha discendenti. Puoi usare 'pushd/popd', o aggiungere' if [["$ 1/*" = "$ i"]]; poi continua; fi' come prima riga dopo 'do'. – Bogdan
$ function f { for i in $1/*; do if [ -d $i ]; then echo $i; f $i; fi; done }
$ mkdir -p 1/2/3 2/3 3
$ f .
./1
./1/2
./1/2/3
./2
./2/3
./3
-1 se fornisci una risposta completa a una domanda a casa, rendila corretta. per quanto riguarda gli spazi nei nomi delle voci di directory? –
e non entra nelle directory e non elenca i file di testo – 18446744073709551615
esso entra nelle directory e l'OP non dice nulla riguardo ai file di testo (o ai file oltre alle directory). Non ho intenzione di risolvere il problema delle 'directory con gli spazi'. –
Qui di seguito è una possibile implementazione:
# my_ls -- recursively list given directory's contents and subdirectories
# $1=directory whose contents to list
# $2=indentation when listing
my_ls() {
# save current directory then cd to "$1"
pushd "$1" >/dev/null
# for each non-hidden (i.e. not starting with .) file/directory...
for file in * ; do
# print file/direcotry name if it really exists...
test -e "$file" && echo "$2$file"
# if directory, go down and list directory contents too
test -d "$file" && my_ls "$file" "$2 "
done
# restore directory
popd >/dev/null
}
# recursively list files in current
# directory and subdirectories
my_ls .
Come esercizio puoi pensare a come modificare l'abov e script per stampare percorsi completi per i file (invece di file/nomi di directory solo indentati), possibilmente eliminando pushd
/popd
(e della necessità del secondo parametro $2
) nel processo.
Per inciso, si noti l'uso di test XYZ && command
che è del tutto equivalente a if test XYZ ; then command ; fi
(cioè eseguire command
se test XYZ
riesce). Si noti inoltre che test XYZ
è equivalente a [ XYZ ]
, vale a dire quanto sopra è equivalente a if [ XYZ ] ; then command ; fi
. Si noti inoltre che qualsiasi punto e virgola ;
può essere sostituito con una nuova riga, sono equivalenti.
Rimuovere la condizione test -e "$file" &&
(lasciare solo il echo
) e vedere cosa succede.
Rimuovere le doppie virgolette intorno a "$file"
e vedere cosa succede quando la directory di cui si sta elencando il contenuto contiene nomi di file con spazi al loro interno. Aggiungi set -x
nella parte superiore dello script (o invocalo come sh -x scriptname.sh
) per attivare l'output di debug e vedere cosa sta succedendo nei dettagli (per reindirizzare l'output di debug su un file, esegui sh -x scriptname.sh 2>debugoutput.txt
).
Per elencare anche i file nascosti (ad esempio .bashrc
):
...
for file in * .?* ; do
if [ "$file" != ".." ] ; then
test -e ...
test -d ...
fi
done
...
Si noti l'uso di !=
(confronto di stringhe) anziché -ne
(confronto numerico.)
Un'altra tecnica sarebbe quella di generare subshells invece di usare pushd
/popd
:
my_ls() {
# everything in between roundbrackets runs in a separatly spawned sub-shell
(
# change directory in sub-shell; does not affect parent shell's cwd
cd "$1"
for file in ...
...
done
)
}
noti che in alcune implementazioni shell v'è un limite rigido (~ 4k) sul numero di caratteri che può essere trasmesso come argomento per for
(o per qualsiasi comando incorporato o esterno per quella materia). Poiché la shell expands, inline, *
to a list of all matching filenames prima di eseguire effettivamente for
su di esso, è possibile incontrare problemi se *
viene espanso all'interno di una directory con molti file (stesso problema ti imbatterai durante l'esecuzione, ad esempio ls *
nella stessa directory, e .es. ottenere un errore come Command too long
.)
puoi usare 'shopt -s dotglob' per elencare i file nascosti. – ghostdog74
@ghostdog - non portatile. '. *' (o '.? *' per saltare '.' off the bat) fa il trucco bene ed è anche portatile. – vladr
Tecnicamente, né find né ls vengono utilizzati da find2perl | perl o File::Find direttamente.
$ find2perl -type d | perl $ perl -MFile::Find -e'find(sub{-d&&print"$File::Find::name\n"},".")'
ma poi, se questo è il caso, usando Python/Ruby/PHP ecc. Qualsiasi linguaggio in grado di elencare i file non sarà tecnicamente usando 'ls' o' find' – ghostdog74
@ ghostdog74 Ovviamente. Ma dal momento che tutte le risposte serie hanno ricevuto feedback meno che sorprendenti, questo è qualcosa ... meno serio. (Stavo per scrivere un clone di 'find' in C e uno script di shell che lo compila + lo esegue, ma ho deciso che era troppo impegnativo per uno scherzo.) – ephemient
Dal momento che è per la bash, è una sorpresa che questo non è stato già detto:
(globstar valida dal bash 4.0+)
shopt -s globstar nullglob dotglob
echo **/*/
Questo è tutto.
La barra finale /
è lì per selezionare solo le directory.
L'opzione globstar
attiva lo **
(ricerca in modo ricorsivo). L'opzione nullglob
rimuove uno *
quando non corrisponde a nessun file/dir. L'opzione dotglob
include file che iniziano con un punto (file nascosti).
- 1. Come faccio a elencare in modo ricorsivo tutte le directory in una posizione, prima di tutto?
- 2. Come utilizzare in modo ricorsivo JpegTran (riga di comando) per ottimizzare tutti i file in sottodirectory?
- 3. Comprende in modo ricorsivo tutte le sottodirectory del modello
- 4. "find" e "ls" con GNU parallel
- 5. Come caricare tutti i file di simboli in modo ricorsivo dal percorso dato comprese le sottodirectory?
- 6. Windows: come elencare i file in modo ricorsivo con le dimensioni e l'ultima data di accesso?
- 7. Come si determinano i colori bash ls?
- 8. Bash find, exclude parent?
- 9. come elencare tutte le sottodirectory in una directory
- 10. Elenca tutte le sottodirectory foglia in linux
- 11. Mostrare i comandi senza eseguirli
- 12. Elenca in modo ricorsivo tutti i file su sftp
- 13. PHP: Come elencare i file in una directory senza sottodirectory sfogliare
- 14. Come utilizzare i comandi SCAN in Jedis
- 15. Come trovare solo i file in una determinata directory e ignorare le sottodirectory usando bash
- 16. Come elencare i file nella directory usando bash?
- 17. Come utilizzare i comandi della shell in Makefile
- 18. Come limitare i risultati del comando find in bash?
- 19. Utilizzo del comando find in bash script
- 20. windows .bat file come elencare in modo ricorsivo tutti i file di tipo * .mp3
- 21. Come eliminare i file in modo ricorsivo
- 22. Come gzip su tutti i file in tutte le sottodirectory in bash
- 23. Come eseguire i comandi zkCli.sh di zookeeper da bash?
- 24. Le varianti si utilizzano in modo ricorsivo?
- 25. HDFS: come si elencano i file in modo ricorsivo?
- 26. Come ordinare i risultati di find (comprese le directory annidate) alfabeticamente in bash
- 27. Perché implementiamo le interfacce in modo ricorsivo?
- 28. Bash: Piping Trova in Grep
- 29. Come elencare tutte le cartelle e le loro sottodirectory/file in iPhone SDK?
- 30. In Perforce, in modo ricorsivo elencare tutti i flussi bambino dato un flusso genitore
Che cosa dovresti usare per fare questo? Il tuo script di shell, un programma C, Java ...? Se ci fai sapere cosa puoi * usare *, l'aiuto dovrebbe essere più immediato :-) – Grundlefleck
Potresti essere in grado di usare 'echo *' o variazioni su quello per emulare 'ls'. Le directory vuote –