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.


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 }'

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

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 .)


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"

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

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"

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 *.


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


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.


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


10

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

ls -lR /path/I/need

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 ...


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

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

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 \{\} \;

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.


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.


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…


4

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


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

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 "/$"          

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]

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.