Commande ls: comment obtenir une liste récursive de chemin complet, une ligne par fichier?

493

Comment puis-je faire en sorte que ls crache une liste plate de chemins récursifs un par ligne?

Par exemple, je veux juste une liste plate de fichiers avec leurs chemins d'accès complets:

/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow
/home/dreftymac/stackoverflow/alpha.txt
/home/dreftymac/stackoverflow/bravo.txt
/home/dreftymac/stackoverflow/charlie.txt

ls -a1 fait presque ce dont j'ai besoin, mais je ne veux pas de fragments de chemin, je veux des chemins complets.

dreftymac
la source
Voir aussi: tree
dreftymac

Réponses:

386

Si vous voulez vraiment l'utiliser ls, formatez sa sortie en utilisant awk:

ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'
ghostdog74
la source
5
@dreftymac, ce qui signifie que c'est, objectivement, la bonne réponse à la question que vous avez écrite, intentionnellement ou non. Oui, ce n'était peut-être pas la bonne réponse à la question que vous espériez avoir écrite. Et bien que je sois d'accord avec votre point le plus important: "lorsque le sage pointe vers la lune, le fou regarde le doigt", il est juste que nous minimisions l'impact de la subjectivité pour évaluer l'exactitude, surtout lorsque les critères n'ont aucune ambiguïté possible
lurscher
1
@dreftymac, je serai heureux de changer mon vote, mais il est maintenant verrouillé, vous devez modifier la question afin que je puisse mettre à jour le vote
lurscher
7
Quelqu'un peut-il expliquer les awkexpressions ci-dessus ?
Mert Nuhoglu
2
Cette solution n'omet pas les répertoires (chaque répertoire a sa propre ligne)
JayB
2
Merci. Btw, ce serait bien d'avoir ceci en 1 ligne pour un copier-coller rapide.
Leo Ufimtsev
567

Utilisez find:

find .
find /home/dreftymac

Si vous ne voulez que des fichiers (omettez les répertoires, les périphériques, etc.):

find . -type f
find /home/dreftymac -type f
stefanB
la source
2
des lsparamètres comme --sort=extension"rachetés" par cette solution?
n611x007
Vous pouvez même utiliser la sortie printf pour afficher les informations contextuelles nécessaires (par exemple find. -Type f -printf '% p% u \ n')
xsubira
Peut-il être formaté avec un falg? c'est à dire. python pprint.pprint (fichiers)
Nathan
72

ls -ld $(find .)

si vous souhaitez trier votre sortie par heure de modification:

ls -ltd $(find .)

autres
la source
11
-bash: / bin / ls: Liste d'arguments trop longue
jperelli
1
+1 a fonctionné pour moi avec 12106 fichiers, et je pouvais utiliser le --sort=extensionparamètre dels
n611x007
3
Merci. Je n'aurais pas pensé par moi-même à cette syntaxe (agréable et courte) - j'aurais utilisé find . -name "*" -exec ls -ld '{}' \;(celle-ci fonctionne quel que soit le nombre de fichiers), mais votre commande est beaucoup plus courte à écrire;)
SRG
1
ls -ld $ (trouver.) pauses pour moi si je liste un disque ntfs où les fichiers ont des espaces: ls: ne peut pas accéder ./System: Aucun fichier ou répertoire trouver mais avec des citations de @SRG fonctionne
kuz8
Une alternative plus courte (selon vos besoins) serait find . -ls.
IanS
59

Essayez la méthode plus simple suivante:

find "$PWD"
Ivan Alegre
la source
9
find "`pwd`"si le chemin contient des espaces ou d'autres caractères spéciaux.
mustafa.0x
7
En quoi est-ce différent find .? -.-
Salman von Abbas
7
@SalmanPK Si vous donnez trouver un chemin absolu comme pwdpour commencer, il imprimera les chemins absolus. Au fait, "En quoi est-ce différent de find" ;-)
yckart
44

La meilleure commande est: tree -fi

Pour utiliser les fichiers mais pas les liens, vous devez supprimer >de votre sortie:

tree -fi |grep -v \>

Si vous souhaitez connaître la nature de chaque fichier, (pour lire uniquement les fichiers ASCII par exemple) avec deux whiles:

tree -fi | \
grep -v \> | \
while read first ; do 
    file ${first}
done | \
while read second; do 
    echo ${second} | grep ASCII
done
Kerkael
la source
Merci, je ne savais pas tree!
Dan Filimon
@Nakilon quelle est la chose la plus proche? Affiche-t-il la sortie de la même manière? Comment afficheriez- vous facilement une sortie similaire avec une commande courte ?
om01
6
@ om01: sur osx, c'est difficile car brew install tree, étant donné que vous utilisez homebrew
ccpizza
je n'ai pas pu lister les fichiers en exclusivité. il répertorie également toujours les répertoires. Comment puis je faire ça?
kommradHomer
Cela devrait être évalué bien plus haut!
der_grund
44

Oh, vraiment une longue liste de réponses. Cela m'a beaucoup aidé et finalement, j'ai créé le mien que je cherchais:

Pour répertorier tous les fichiers d'un répertoire et de ses sous-répertoires:

find "$PWD" -type f

Pour répertorier tous les répertoires d'un répertoire et de ses sous-répertoires:

find "$PWD" -type d

Pour répertorier tous les répertoires et fichiers d'un répertoire et de ses sous-répertoires:

find "$PWD"
Parrain
la source
2
Et pour filtrer par extension:find "$PWD" -type f | grep '\.json$'
Killroy
2
Pas besoin de post-traitement avec grep, utilisez -name dans find like: find "$ PWD" -type f -name * .json et si vous voulez supprimer les fichiers listés: find "$ PWD" -type f -name * .json -exec rm {} \; de même, si vous voulez le copier, remplacez rm par cp et destination: -exec cp {} destination
Parrain
18

Je ne connais pas le chemin complet, mais vous pouvez utiliser -Rpour la récursivité. Alternativement, si vous n'êtes pas déterminé ls, vous pouvez simplement le faire find *.

Justin Johnson
la source
16

N'utiliser aucune commande externe autre que ls:

ls -R1 /path | 
  while read l; do case $l in *:) d=${l%:};; "") d=;; *) echo "$d/$l";; esac; done

Idélique
la source
Option inconnue «-1». Abandon.
ilw
15
du -a

Pratique pour certains boîtiers d'appareils limités où la recherche / localisation n'est pas disponible.

Rob D
la source
1
une idée comment je peux supprimer le fichier sans la taille awk?
Arnold Roa
12

trouver / fera l'affaire

Dmitry
la source
10

Ne compliquez pas les choses. Je viens de l'utiliser et j'ai obtenu une belle sortie:

ls -lR /path/I/need
KellyC
la source
3
OP veut juste le chemin complet et rien d'autre. ls -lRn'atteindrait pas cet objectif.
codeforester
désolé, il ne le fait pas
Aryeh Beitz
9

La façon la plus simple pour vous tous, futurs gens, est simplement:

du

Cependant, cela montre également la taille de ce qui est contenu dans chaque dossier.Vous pouvez utiliser awk pour afficher uniquement le nom du dossier:

du | awk '{print $2}'

Edit- Désolé désolé, ma mauvaise. Je pensais que seuls les dossiers étaient nécessaires. Je vais laisser ça ici au cas où quelqu'un à l'avenir en aurait besoin de toute façon ...

6112115
la source
Intéressant, car il me montre des choses que je ne savais pas que je voulais savoir - un peu comme Google suggère. Il s'avère que j'aime savoir combien d'espace chaque fichier prend.
Jake Toronto
9

Avec la liberté d'utiliser toutes les options ls possibles:

find -type f | xargs ls -1

Grzegorz Luczywo
la source
9

Je pense que pour une liste plate, la meilleure façon est:

find -D tree /fullpath/to-dir/ 

(ou pour l'enregistrer dans un fichier txt)

find -D tree /fullpath/to-dir/ > file.txt
Dimitrios
la source
3
Testé sur Mac OS 10.13.3. find: illegal option -- D
Jayant Bhawal
8

Exécutez une commande bash au format suivant:

find /path -type f -exec ls -l \{\} \;
Denio Mariz
la source
6

Voici une réponse partielle qui montre les noms de répertoire.

ls -mR * | sed -n 's/://p'

Explication:

ls -mR * répertorie les noms de répertoire complets se terminant par un «:», puis répertorie les fichiers dans ce répertoire séparément

sed -n 's/://p' trouve les lignes qui se terminent par deux points, enlevez les deux points et imprimez la ligne

En parcourant la liste des répertoires, nous devrions également pouvoir trouver les répertoires. Je travaille toujours dessus. C'est un défi d'obtenir les caractères génériques à travers les xargs.

Kevin
la source
excellente réponse .. exactement ce dont j'avais besoin!
Selvin
5

L'ajout d'un caractère générique à la fin d'un répertoire ls force les chemins d'accès complets. En ce moment, vous avez ceci:

$ ls /home/dreftymac/
foo.txt
bar.txt
stackoverflow
stackoverflow/alpha.txt
stackoverflow/bravo.txt
stackoverflow/charlie.txt

Vous pouvez le faire à la place:

$ ls /home/dreftymac/*
/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow:
alpha.txt
bravo.txt
charlie.txt

Malheureusement, cela n'imprime pas le chemin complet des répertoires récurrents, il ne s'agit donc peut-être pas de la solution complète que vous recherchez.

koeselitz
la source
Malheureusement, vous ne pouvez pas non plus créer de sudo ls avec un caractère générique (car le caractère générique est développé en tant qu'utilisateur normal).
Andrew Lorien
4

Beaucoup de réponses que je vois. C'est le mien, et je pense que c'est très utile si vous travaillez sur Mac.

Je suis sûr que vous savez qu'il existe des fichiers "bundle" ( .app , .rtfd , .workflow , etc.). Et en regardant la fenêtre du Finder, ils semblent des fichiers uniques. Mais ce n'est pas le cas. Et $ lsou $ findvoyez-les comme des répertoires ... Donc, à moins que vous n'ayez besoin de répertorier également leur contenu, cela fonctionne pour moi:

find . -not -name ".*" -not -name "." | egrep -v "\.rtfd/|\.app/|\.lpdf/|\.workflow/"

Bien sûr, c'est pour le répertoire de travail, et vous pouvez ajouter d'autres extensions de bundles (mais toujours avec un /après eux). Ou toute autre extension si ce n'est pas un bundle sans le /.

Plutôt intéressant le " .lpdf/" (pdf multilingue). Il a une .pdfextension " " normale (!!) ou aucune dans le Finder. De cette façon, vous obtenez (ou il ne compte qu'un seul fichier) pour cela pdfet pas un tas de choses…

Steve
la source
4

ls -lR c'est ce que vous cherchiez, ou du moins j'étais. à votre santé

sivi
la source
OP veut juste le chemin complet et rien d'autre. ls -lRn'atteindrait pas cet objectif.
Hadrien TOMA
3

Si le répertoire est passé en tant que chemin relatif et que vous devrez le convertir en chemin absolu avant d'appeler find. Dans l'exemple suivant, le répertoire est transmis en tant que premier paramètre au script:

#!/bin/bash

# get absolute path
directory=`cd $1; pwd`
# print out list of files and directories
find $directory
John Keyes
la source
Si votre système en dispose, readlinkvous pouvez le fairedirectory=$(readlink -e $1)
pause jusqu'à nouvel ordre.
Certes, mais la combinaison cd / pwd fonctionnera sur tous les systèmes. readlinksous OS X 10.5.8 ne prend pas en charge l'option -e.
John Keyes
3
tar cf - $PWD|tar tvf -             

Ceci est lent mais fonctionne récursivement et imprime à la fois les répertoires et les fichiers. Vous pouvez le diriger avec awk / grep si vous voulez juste les noms de fichiers sans toutes les autres informations / répertoires:

tar cf - $PWD|tar tvf -|awk '{print $6}'|grep -v "/$"          
RuleB
la source
2
vous pouvez également utiliser simplement: tar cvf / dev / null $ PWD
RuleB
2

@ ghostdog74: Petit ajustement avec votre solution.
Le code suivant peut être utilisé pour rechercher un fichier avec son chemin absolu complet.

sudo ls -R / | awk '<br/>
/:$/&&f{s=$0;f=0}<br/>
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}<br/>
NF&&f{ print s"/"$0 }' | grep [file_to_search]
Chaitanya
la source
1

Je connaissais le nom du fichier mais je voulais aussi le répertoire.

trouver $ PWD | nom de fichier fgrep

fonctionnait parfaitement sous Mac OS 10.12.1

hpj
la source