Wie kann ich unter Linux eine Liste von Dateien mit ihrem absoluten Pfad erstellen?


304

Ich schreibe ein Shell-Skript, das Dateipfade als Eingabe verwendet.

Aus diesem Grund muss ich rekursive Dateilisten mit vollständigen Pfaden generieren. Zum Beispiel hat die Datei barden Pfad:

/home/ken/foo/bar

aber soweit ich sehen kann, geben beide lsund findnur relative Pfadlisten an:

./foo/bar   (from the folder ken)

Es scheint eine offensichtliche Anforderung zu sein, aber ich kann auf den findoder lsManpages nichts sehen .

Wie kann ich eine Liste der Dateien in der Shell einschließlich ihrer absoluten Pfade erstellen?


Verwenden Sie:find /home/ken/foo/bar -exec ls -ld $PWD/{} \;
Lerner

Antworten:


305

Wenn Sie zunächst findeinen absoluten Pfad angeben, werden absolute Pfade gedruckt. So finden Sie beispielsweise alle .htaccess-Dateien im aktuellen Verzeichnis:

find "$(pwd)" -name .htaccess

oder wenn Ihre Shell $PWDin das aktuelle Verzeichnis erweitert wird:

find "$PWD" -name .htaccess

find Stellen Sie einfach den Pfad, den es erhalten hat, einem relativen Pfad zur Datei von diesem Pfad voran.

Greg Hewgill schlug außerdem vor pwd -P, Symlinks in Ihrem aktuellen Verzeichnis aufzulösen.


9
Beachten Sie, dass Sie verwenden, wenn Sie auch Symlinks auflösen möchten pwd -P.
Greg Hewgill

5
Dies ist hilfreich, aber ich denke, Benutzer431529 Antwort unten ist mehr gültig: ls -d -1 $PWD/**/*aber ich denke, find $PWDfunktioniert auch (in Bash getestet)
Brian

9
@ Brian Warum? find $PWDIst einfach. Die lsBeschwörung ist komplex und unhandlich (es sei denn, Sie alias es). findist nicht abhängig von Shell-Glob-Erweiterungen, funktioniert also in jeder Shell. findist auch viel flexibler, ich kann eine rekursive Liste aller Dateien oder vielleicht aller Verzeichnisse erhalten, oder vielleicht möchte ich eine Liste aller XML-Dateien oder aller Dateien, die in der letzten Woche geändert wurden. All das ist möglich mit find, aber nicht einfach mit ls.
Matthew Scharley

12
Ich musste find "`pwd`" -name .htaccesswegen Leerzeichen in Verzeichnisnamen verwenden
Paulo Casaretto

Ich verstehe es nicht, dieser Befehl gibt mir nicht den absoluten Pfad der Datei I, während andere Antworten auf der Liste den Job erledigen.
Bjørn Otto Vasbotten

202
readlink -f filename 

gibt den vollen absoluten Weg an. Wenn es sich bei der Datei jedoch um einen Symlink handelt, erhalten Sie den endgültig aufgelösten Namen.


8
Nett. Funktioniert nicht mit der BSD-Variante von readlink (dh Mac). Ich verwende Gnucoreutils auf Mac. Und kann daher Greadlink verwenden, der mit der obigen Lösung funktioniert.
Sheki

12
No go on Mac OS X.
Andrew Lazarus

1
@ AndrewLazarus - Für Mac OS X verwenden Sie realpathstattdessen
cz

Wenn Sie Bash-Tools über installieren brew install coreutils, wird die ausführbare Datei als/usr/local/opt/coreutils/libexec/gnubin/readlink
redolent

121

Verwenden Sie diese für dirs (die /nach dem **in bash benötigt wird , es auf Verzeichnisse zu begrenzen):

ls -d -1 "$PWD/"**/

Dies gilt für Dateien und Verzeichnisse direkt unter dem aktuellen Verzeichnis, deren Namen Folgendes enthalten .:

ls -d -1 "$PWD/"*.*

das für alles:

ls -d -1 "$PWD/"**/*

Von hier genommen http://www.zsh.org/mla/users/2002/msg00033.html

In Bash **ist rekursiv, wenn Sie aktivieren shopt -s globstar.


1
ls -d -1 $ PWD / ** / * wird nicht wiederholt. Ich wünschte, ich könnte meine +1 zurücknehmen. Sie können ** für jede Tiefe tun, die Sie gehen müssen.
user606723

4
Der Operator ** ist ein rekursiver Globbing-Operator. Wenn Sie den Befehl in einer Shell verwenden, die ihn unterstützt (z. B. zsh), funktioniert er ordnungsgemäß.
Zebediah49

ls -d1 "$ PWD /"{*,.*}, um auch die versteckten (Punkt-) Dateien abzufangen. Für mich hat die rekursive Version in der Antwort den absoluten Pfad zu Dateien in Unterordnern nicht vorangestellt.
Zael

Ich denke, ich muss find verwenden ... Ich bekomme -> bash: / bin / ls: Argumentliste zu lang
TelamonAegisthus

30

Sie können verwenden

find $PWD 

in bash


3
Dadurch werden der Pfad des aktuellen Verzeichnisses sowie alle Dateien und Verzeichnisse darunter angegeben. Das ist wahrscheinlich nicht das, wonach die Leute suchen.
Bill

18
ls -d "$PWD/"*

Dies sieht nur im aktuellen Verzeichnis aus. Es zitiert "$ PWD", falls es Leerzeichen enthält.


Dies ist immer noch eine sehr gültige Antwort, aber es wäre gut, die Information aufzunehmen, dass dies nicht rekursiv funktioniert (was ich tatsächlich gesucht habe!)
bbbco

1
Für die rekursive Verwendung: find. -exec ls -ld $ PWD / {} \;
Lerner

10

Befehl: ls -1 -d "$PWD/"*

Dies gibt die absoluten Pfade der Datei wie unten an.

[root@kubenode1 ssl]# ls -1 -d "$PWD/"*
/etc/kubernetes/folder/file-test-config.txt
/etc/kubernetes/folder/file-test.txt
/etc/kubernetes/folder/file-client.txt

8

Das $PWDist eine gute Option von Matthew oben. Wenn Sie möchten, dass find nur Dateien druckt, können Sie auch die Option -type f hinzufügen, um nur normale Dateien zu durchsuchen. Andere Optionen sind "d" nur für Verzeichnisse usw. In Ihrem Fall wäre es also (wenn ich nur nach Dateien mit .c ext suchen möchte):

find $PWD -type f -name "*.c" 

oder wenn Sie alle Dateien wollen:

find $PWD -type f

Hinweis: Sie können keinen Alias ​​für den obigen Befehl erstellen, da $ PWD automatisch in Ihrem Home-Verzeichnis vervollständigt wird, wenn der Alias ​​von bash festgelegt wird.


Eigentlich bedeutet -d nicht nur Verzeichnisse - es bedeutet, dass Verzeichnisse wie Dateien behandelt werden. Wenn Sie also -d / home haben, erhalten Sie "/ home" zurück, keine Auflistung der Inhalte / home.
Travis

@Travis: Er sprach über die Option zu finden, nicht ls. In seinem Fall würde "find / -type d" nur Verzeichnisse finden - wie er sagte.
Oligofren

6

Wenn Sie dem Befehl find einen absoluten Pfad geben, werden die Ergebnisse mit einem absoluten Pfad ausgespuckt. Also, aus dem Ken-Verzeichnis, wenn Sie Folgendes eingeben würden:

find /home/ken/foo/ -name bar -print    

(anstelle des relativen Pfades find . -name bar -print)

Du solltest bekommen:

/home/ken/foo/bar

Wenn Sie also einen möchten ls -lund den absoluten Pfad zurückgeben möchten , können Sie dem Befehl find einfach anweisen, einen Befehl für ls -lalles auszuführen, was er findet.

find /home/ken/foo -name bar -exec ls -l {} ;\ 

HINWEIS: Zwischen {}und befindet sich ein Leerzeichen;

Sie werden so etwas bekommen:

-rw-r--r--   1 ken admin       181 Jan 27 15:49 /home/ken/foo/bar

Wenn Sie nicht sicher sind, wo sich die Datei befindet, können Sie den Suchort jederzeit ändern. Solange der Suchpfad mit "/" beginnt, erhalten Sie im Gegenzug einen absoluten Pfad. Wenn Sie nach einem Ort suchen (wie /), an dem Sie viele Fehler erhalten, denen die Berechtigung verweigert wurde, würde ich empfehlen, Standardfehler umzuleiten, damit Sie die Suchergebnisse tatsächlich sehen können:

find / -name bar -exec ls -l {} ;\ 2> /dev/null

( 2>ist die Syntax für die Borne- und Bash-Shells, funktioniert aber nicht mit der C-Shell. Sie funktioniert möglicherweise auch in anderen Shells, aber ich weiß nur sicher, dass sie in Bourne und Bash funktioniert.)


Sie können mit mehrere Argumente an denselben lsProzess übergeben -exec ls -ld {} +. (Sie möchten wahrscheinlich -dkeinen lsListenverzeichnisinhalt haben ). Oder besser, verwenden Sie die integrierte Funktion von find lsmit find ... name bar -ls. Außerdem ist die Syntax für ein Argument pro Befehl falsch: Sie müssen das Semikolon aus der Shell in Anführungszeichen setzen {} \;.
Peter Cordes

5

fd

Verwenden Sie fd(alternativ zu find) die folgende Syntax:

fd . foo -a

Wo .ist das Suchmuster und fooist das Stammverzeichnis.

Um beispielsweise alle Dateien etcrekursiv aufzulisten, führen Sie Folgendes aus : fd . /etc -a.

-a, --absolute-path Absolute statt relative Pfade anzeigen


2

Nur eine Alternative zu

ls -d "$PWD/"* 

um genau zu bestimmen, dass *es sich um eine Shell-Erweiterung handelt

echo "$PWD/"*

würde das gleiche tun (der Nachteil, den Sie nicht verwenden können -1, um durch neue Zeilen zu trennen, nicht durch Leerzeichen).


Können Sie das näher erläutern? Was ist eine Shell-Erweiterung? Wie verwende -1ich das Trennen durch Linien?
Antonio Araujo

@Antonio Araujo, Shell-Erweiterung ist die Shell (zB Bash), die * durch eine Liste von Dateien ersetzt - mehr dazu auf der Bash-Manpage. -1 ist ls Befehlsoption, echo ist ein anderer Befehl, es gibt nicht die gleichen Optionen.
Marisha

1
lspwd() { for i in $@; do ls -d -1 $PWD/$i; done }

1

Hier ist ein Beispiel, das eine Liste ohne zusätzlichen Punkt ausdruckt und das auch zeigt, wie nach einer Dateimatchung gesucht wird. Hoffe das hilft:

find . -type f -name "extr*" -exec echo `pwd`/{} \; | sed "s|\./||"

1

Das hat bei mir funktioniert. Aber es wurde nicht in alphabetischer Reihenfolge aufgelistet.

find "$(pwd)" -maxdepth 1

Dieser Befehl listet sowohl alphabetisch als auch versteckte Dateien auf.

ls -d -1 "$PWD/".*; ls -d -1 "$PWD/"*;

1

stat

Absoluter Pfad einer einzelnen Datei:

stat -c %n "$PWD"/foo/bar

1

Vielleicht möchten Sie dies versuchen.

for name in /home/ken/foo/bar/*
do
    echo $name
done

Sie können abs Pfad mit forSchleife und echoeinfach ohne erhalten find.


0

Wenn Sie eine Liste aller Dateien in aktuellen sowie Unterverzeichnissen benötigen

find $PWD -type f

Wenn Sie eine Liste aller Dateien nur im aktuellen Verzeichnis benötigen

find $PWD -maxdepth 1 -type f

0

Dies gibt den kanonischen Pfad an (löst Symlinks auf): realpath FILENAME

Wenn Sie einen kanonischen Pfad zum Symlink selbst möchten, dann: realpath -s FILENAME


0

Die meisten, wenn nicht alle vorgeschlagenen Methoden führen zu Pfaden, die nicht direkt in einem anderen Terminalbefehl verwendet werden können, wenn der Pfad Leerzeichen enthält. Im Idealfall werden den Ergebnissen Schrägstriche vorangestellt. Das funktioniert bei mir unter macOS:

find / -iname "*SEARCH TERM spaces are okay*" -print 2>&1  | grep -v denied |grep -v permitted |sed -E 's/\ /\\ /g'

-1

find / -print werde das tun


1
... leider wird es etwas anderes tun (wie das Anzeigen einiger anderer Dateien, sofern nicht gefiltert)
DerMike

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.