"Find" Ausgabe relativ zum Verzeichnis

34

Ich möchte verwenden, findum alle Dateien und Verzeichnisse in einem bestimmten Stammverzeichnis für eine cpioOperation rekursiv aufzulisten. Ich möchte jedoch nicht, dass das Stammverzeichnis selbst in den Pfaden angezeigt wird. Zum Beispiel bekomme ich momentan:

$ find diskimg
diskimg
diskimg/file1
diskimg/dir1
diskimg/dir1/file2

Aber ich würde gerne bekommen

file1
dir1
dir1/file2

(Beachten Sie, dass die Wurzel auch nicht in meiner gewünschten Ausgabe ist, aber das ist leicht zu entfernen tail).

Ich arbeite unter OS X und würde es vorziehen, wenn möglich keine zusätzlichen Tools (z. B. GNU find) zu installieren, da ich das Skript, das ich schreibe, mit anderen OS X-Benutzern teilen möchte.

Ich bin mir bewusst, dass dies getan werden kann cut, um das Root-Listing abzuschneiden, aber das scheint eine suboptimale Lösung zu sein. Gibt es eine bessere Lösung?

nneonneo
quelle
find diskimg/* | cut -d '/' -f2-
nik.shornikov

Antworten:

18

Wenn das, was Sie versuchen, nicht zu komplex ist, können Sie dies mit sed erreichen:

find diskimg | sed -n 's|^diskimg/||p'

Oder cut:

find diskimg | cut -sd / -f 2-
BriGuy
quelle
Sie können (fast) jedes Trennzeichen für den Befehl auswählen, also: find diskimg | grep -v '^diskimg$' | sed -e 's|^diskimg/||'(Beachten Sie, dass ich auch '-e' hinzugefügt habe, und eine ^ebenso gute Übung (hier nicht erforderlich, da Sie sicher sind, dass jede Zeile diese haben wird ... aber immer noch eine gute Übung und spart etwas CPU;))
Olivier Dulac
ein anderer weg ohne grep: find diskimg | sed -e 's|^diskimg/*||' (das '/ *'
Olivier Dulac
Dieser cutBefehl ist sauberer als der, den ich verwendet habe. Ich mag das. (Die sedLösung ist auch schön, aber die Wiederholung von diskimg/ist ein wenig unglücklich).
Nneonneo
30

cd zuerst in das Verzeichnis:

cd diskimg && find . 

Nach Abschluss des Vorgangs befinden Sie sich wieder in Ihrem Stammverzeichnis.

Ihren Dateien wird in diesem Fall ./ vorangestellt. die einzige Möglichkeit, die ich sehe, wäre die Verwendung von cut:

{ cd diskimg && find .; } | tail -n +2 | cut -c 3-

Verwenden Sie eine Subshell, um zu vermeiden, dass das aktuelle Verzeichnis Ihrer Shell geändert wird (dies ist nicht erforderlich, wenn Sie die Ausgabe weiterleiten, da die linke Seite einer Pipe bereits in einer Subshell ausgeführt wird).

(cd diskimg && find .)
Stephan
quelle
5
im ursprünglichen Verzeichnis nach Abschluss zurück zu sein: in Klammern: (cd diskimg && find . ; ). Auf diese Weise wird das cd diskimg && find .in einer Subshell erledigt: Wenn diese Subshell beendet wird, kehren Sie zu Ihrer eigenen Shell zurück, in welchem ​​Verzeichnis auch immer Sie sich befanden.
Olivier Dulac
1
find *ist ein anderer Weg um das nutzlose Präfix
nik.shornikov
23

Ein anderer, komplexerer Ansatz, der jedoch nur den Suchansatz aus meiner anderen Antwort verwendet:

find diskimg -mindepth 1 -printf '%P\n'
Stephan
quelle
Nicht alle findSupport- Versionen printf.
Jordanien
1
Sicherlich; Mein OSX scheint das nicht zu tun. Zum Teil, warum ich eine andere Lösung angeboten habe.
Stephan
2
@Stephan - beim nächsten Mal können Sie diese Art von Antworten einfach zu einer einzigen kombinieren. Für solche Abweichungen müssen keine Mehrfachantworten gegeben werden.
slm
2
Nur GNU findunterstützt -printf, während viele BSDs findeinige der Funktionen von GNU findkopiert haben, hat -printfnoch keine kopiert (AFAIK).
Stéphane Chazelas
Das %Pfür den relativen Pfad war das, was ich brauchte.
Fl0v0
4

Verwenden Sie das realpathDienstprogramm:

find diskimg -exec realpath --relative-to diskimg {} \;
Dwjbosman
quelle
Schön - danke, dass du es mir gezeigt hast --relative-to.
Nneonneo