ls Befehl: Wie kann ich eine rekursive vollständige Pfadliste erhalten, eine Zeile pro Datei?


493

Wie kann ich ls dazu bringen, eine flache Liste rekursiver Pfade pro Zeile auszuspucken?

Zum Beispiel möchte ich nur eine flache Liste von Dateien mit ihren vollständigen Pfaden:

/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 macht fast das, was ich brauche, aber ich möchte keine Pfadfragmente, ich möchte vollständige Pfade.


Siehe auch: Baum
Dreftymac

Antworten:


386

Wenn Sie wirklich verwenden möchten ls, formatieren Sie die Ausgabe mit awk:

ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'

5
@dreftymac, was bedeutet, dass dies objektiv gesehen die richtige Antwort auf die Frage ist, die Sie absichtlich oder absichtlich geschrieben haben. Ja, möglicherweise war es nicht die richtige Antwort auf die Frage, die Sie sich erhofft hatten. Und obwohl ich Ihrem größeren Punkt zustimme: "Wenn der Weise auf den Mond zeigt, schaut der Narr auf den Finger", ist es nur fair, dass wir den Einfluss der Subjektivität auf die Bewertung der Korrektheit minimieren, insbesondere wenn die Kriterien keine mögliche Mehrdeutigkeit aufweisen
Lurscher

1
@dreftymac, ich werde froh sein, meine Abstimmung zu ändern, aber es ist jetzt gesperrt, Sie müssen die Frage bearbeiten, damit ich die Abstimmung aktualisieren kann
lurscher

7
Kann jemand bitte die obigen awkAusdrücke erklären ?
Mert Nuhoglu

2
Diese Lösung lässt die Verzeichnisse nicht aus (jedes Verzeichnis erhält eine eigene Zeile)
JayB

2
Vielen Dank. Übrigens wäre es schön, dies in einer Zeile zum schnellen Kopieren und Einfügen zu haben.
Leo Ufimtsev

567

Verwenden Sie find:

find .
find /home/dreftymac

Wenn Sie nur Dateien möchten (Verzeichnisse, Geräte usw. weglassen):

find . -type f
find /home/dreftymac -type f

2
können lsParameter wie --sort=extension"eingelöst" durch diese Lösung?
n611x007

Sie können sogar die printf-Ausgabe verwenden, um die erforderlichen Kontextinformationen anzuzeigen (z. B. find. -Type f -printf '% p% u \ n')
xsubira

Kann dies mit einem Falg formatiert werden? dh. Python pprint.pprint (Dateien)
Nathan

72

ls -ld $(find .)

Wenn Sie Ihre Ausgabe nach Änderungszeit sortieren möchten:

ls -ltd $(find .)


11
-bash: / bin / ls: Argumentliste zu lang
jperelli

1
+1 arbeitete für mich mit 12106 Dateien, und ich konnte den --sort=extensionParameterls
n611x007

3
Vielen Dank. Ich hätte mir diese (nette und kurze) Syntax nicht selbst überlegt - ich hätte sie verwendet find . -name "*" -exec ls -ld '{}' \;(diese funktioniert unabhängig von der Anzahl der Dateien), aber Ihr Befehl ist viel kürzer zu schreiben;)
SRG

1
ls -ld $ (find.) bricht für mich ab, wenn ich eine ntfs-Festplatte aufführe, auf der Dateien Leerzeichen enthalten: ls: kann nicht auf ./System zugreifen: Keine solche Datei oder kein solches Verzeichnis finden Sie jedoch mit Anführungszeichen von @SRG works
kuz8

Eine kürzere Alternative (abhängig von Ihren Bedürfnissen) wäre find . -ls.
IanS

59

Versuchen Sie den folgenden einfacheren Weg:

find "$PWD"

9
find "`pwd`"wenn der Pfad Leerzeichen oder andere Sonderzeichen enthält.
mustafa.0x

7
Wie ist das anders als find .? -.-
Salman von Abbas

7
@SalmanPK Wenn Sie find einen absoluten Pfad angeben, mit dem Sie beginnen möchten pwd, werden absolute Pfade gedruckt. Übrigens "Wie ist das anders als find" ;-)
yckart

44

Der beste Befehl ist: tree -fi

Um die Dateien, aber nicht die Links zu verwenden, müssen Sie Folgendes >aus Ihrer Ausgabe entfernen :

tree -fi |grep -v \>

Wenn Sie die Art jeder Datei kennen möchten (um beispielsweise nur ASCII-Dateien zu lesen), mit zwei whiles:

tree -fi | \
grep -v \> | \
while read first ; do 
    file ${first}
done | \
while read second; do 
    echo ${second} | grep ASCII
done

Danke, ich wusste nichts davon tree!
Dan Filimon

@ Nakilon was ist das nächste? Zeigt es die Ausgabe ähnlich an? Wie würden Sie mit einem kurzen Befehl einfach eine ähnliche Ausgabe anzeigen ?
Om01

6
@ om01: auf osx ist es schwierig brew install tree, da Sie Homebrew verwenden
ccpizza

Ich konnte die Dateien nicht exklusiv auflisten. Es werden immer auch die Verzeichnisse aufgelistet. wie kann ich das machen?
kommradHomer

Dies sollte viel höher bewertet werden!
der_grund

44

Oh, wirklich eine lange Liste von Antworten. Es hat mir sehr geholfen und schließlich habe ich mein eigenes erstellt, nach dem ich gesucht habe:

So listen Sie alle Dateien in einem Verzeichnis und seinen Unterverzeichnissen auf:

find "$PWD" -type f

So listen Sie alle Verzeichnisse in einem Verzeichnis und seinen Unterverzeichnissen auf:

find "$PWD" -type d

So listen Sie alle Verzeichnisse und Dateien in einem Verzeichnis und seinen Unterverzeichnissen auf:

find "$PWD"

2
Und nach Erweiterung zu filtern:find "$PWD" -type f | grep '\.json$'
Killroy

2
Keine Nachbearbeitung mit grep erforderlich, verwenden Sie -name in find wie: find "$ PWD" -Typ f -name * .json und wenn Sie die aufgelisteten Dateien löschen möchten: find "$ PWD" -Typ f -name * .json -exec rm {} \; Wenn Sie es kopieren möchten, ersetzen Sie rm durch cp und destination: -exec cp {} destination
Godfather

18

Ich weiß nicht über den vollständigen Pfad Bescheid, aber Sie können ihn -Rfür die Rekursion verwenden. Alternativ können Sie es auch tun, wenn Sie nicht darauf lsaus sind find *.


16

Verwenden Sie keine anderen externen Befehle als ls:

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


Unbekannte Option '-1'. Abbruch.
Ilw

15
du -a

Praktisch für einige begrenzte Gerätegehäuse, bei denen Suchen / Suchen nicht verfügbar ist.


1
Irgendeine Idee, wie ich die Dateigröße ohne entfernen kann awk?
Arnold Roa


10

Mach es nicht kompliziert. Ich habe das gerade benutzt und eine schöne Ausgabe bekommen:

ls -lR /path/I/need

3
OP will nur den vollen Weg und sonst nichts. ls -lRwürde dieses Ziel nicht erreichen.
Codeforester

Entschuldigung, es tut es nicht
Aryeh Beitz

9

Der einfachste Weg für alle zukünftigen Menschen ist einfach:

du

Dies zeigt jedoch auch die Größe der Inhalte in den einzelnen Ordnern. Mit awk können Sie nur den Ordnernamen ausgeben:

du | awk '{print $2}'

Edit- Sorry sorry, mein schlechtes. Ich dachte, es würden nur Ordner benötigt. Ich lasse das hier, falls jemand es in Zukunft sowieso braucht ...


Interessant, weil es mir Dinge zeigt, von denen ich nicht wusste, dass ich sie wissen wollte - so wie Google es vorschlägt. Es stellt sich heraus, dass ich gerne weiß, wie viel Speicherplatz jede Datei benötigt.
Jake Toronto


9

Ich denke für eine flache Liste ist der beste Weg:

find -D tree /fullpath/to-dir/ 

(oder um es in einer txt-Datei zu speichern)

find -D tree /fullpath/to-dir/ > file.txt

3
Versucht unter Mac OS 10.13.3. find: illegal option -- D
Jayant Bhawal

8

Führen Sie einen Bash-Befehl mit dem folgenden Format aus:

find /path -type f -exec ls -l \{\} \;

6

Hier ist eine Teilantwort, die die Verzeichnisnamen zeigt.

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

Erläuterung:

ls -mR * listet die vollständigen Verzeichnisnamen auf, die mit einem ':' enden, und listet dann die Dateien in diesem Verzeichnis separat auf

sed -n 's/://p' Findet Zeilen, die in einem Doppelpunkt enden, entfernen den Doppelpunkt und drucken die Zeile

Durch Durchlaufen der Liste der Verzeichnisse sollten wir auch die Verzeichnisse finden können. Ich arbeite immer noch daran. Es ist eine Herausforderung, die Wildcards durch Xargs zu bekommen.


tolle Antwort .. genau das, was ich brauchte!
Selvin

5

Durch Hinzufügen eines Platzhalters am Ende eines ls-Verzeichnisses werden vollständige Pfade erzwungen. Im Moment haben Sie Folgendes:

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

Sie könnten dies stattdessen tun:

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

Leider wird hiermit nicht der vollständige Pfad für die rekursiven Verzeichnisse gedruckt, sodass möglicherweise nicht die vollständige Lösung angezeigt wird, nach der Sie suchen.


Leider können Sie auch nicht mit einem Platzhalter sudo ls (da der Platzhalter als normaler Benutzer erweitert wird).
Andrew Lorien

4

Viele Antworten sehe ich. Dies ist meine, und ich denke sehr nützlich, wenn Sie auf einem Mac arbeiten.

Ich bin sicher, Sie wissen, dass es einige "Bundle" -Dateien gibt ( .app , .rtfd , .workflow usw.). Und wenn sie in Finders Fenster schauen, scheinen sie einzelne Dateien zu sein. Aber das sind sie nicht. Und $ lsoder $ findsehen Sie sie als Verzeichnisse ... Wenn Sie also nicht auch deren Inhalt auflisten müssen, funktioniert dies für mich:

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

Dies gilt natürlich für das Arbeitsverzeichnis, und Sie können die Erweiterungen anderer Bundles hinzufügen (jedoch immer mit einem /Nachher). Oder andere Erweiterungen, wenn nicht Bundles ohne die /.

Eher interessant das " .lpdf/" (mehrsprachiges pdf). Es hat eine normale " .pdf" Erweiterung (!!) oder keine im Finder. Auf diese Weise erhalten Sie (oder es zählt nur 1 Datei) dafür pdfund nicht ein paar Sachen ...


4

ls -lR ist das, wonach du gesucht hast, oder zumindest war ich es. Prost


OP will nur den vollen Weg und sonst nichts. ls -lRwürde dieses Ziel nicht erreichen.
Hadrien TOMA

3

Wenn das Verzeichnis als relativer Pfad übergeben wird und Sie es in einen absoluten Pfad konvertieren müssen, bevor Sie find aufrufen. Im folgenden Beispiel wird das Verzeichnis als erster Parameter an das Skript übergeben:

#!/bin/bash

# get absolute path
directory=`cd $1; pwd`
# print out list of files and directories
find $directory

Wenn Ihr System dies hat readlink, können Sie dies tundirectory=$(readlink -e $1)
Bis auf weiteres angehalten.

Stimmt, aber die CD / PWD-Kombination funktioniert auf jedem System. readlinkUnter OS X 10.5.8 wird die Option -e nicht unterstützt.
John Keyes

3
tar cf - $PWD|tar tvf -             

Dies ist langsam, funktioniert jedoch rekursiv und druckt sowohl Verzeichnisse als auch Dateien. Sie können es mit awk / grep weiterleiten, wenn Sie nur die Dateinamen ohne alle anderen Informationen / Verzeichnisse möchten:

tar cf - $PWD|tar tvf -|awk '{print $6}'|grep -v "/$"          

2
Sie können auch einfach verwenden: tar cvf / dev / null $ PWD
RegelB

2

@ Ghostdog74: Kleine Optimierung mit Ihrer Lösung.
Der folgende Code kann verwendet werden, um Dateien mit ihrem vollständigen absoluten Pfad zu durchsuchen.

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

Ich kannte den Dateinamen, wollte aber auch das Verzeichnis.

finde $ PWD | fgrep Dateiname

funktionierte perfekt unter Mac OS 10.12.1

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.