2009-11-05 3 views
7

Ich verwende oft das ausgezeichnete Programm find in Bash, um Dateien mit bestimmten Filtern aufzulisten. Zum Beispiel in einem Subversion (SVN) Arbeitskopie, ich möchte manchmal rekursiv alle Dateien auflisten, aber mit Ausnahme der .svn Verzeichnisse wie folgt:Bash-Befehl zum rekursiven Auflisten von Dateien, aber Sortieren nach Klassifizierung

find . -name '.svn' -prune -o -type f -print 

Heute wollte ich etwas Ähnliches tun, aber ich wollte auch beeinflussen Die Reihenfolge, in der die Verzeichnisinhalte aufgelistet wurden: Ich wollte, dass 'normale' Dateien von Unterverzeichnissen gefolgt werden (und dann die rekursiven Inhalte). Es scheint keine Option dafür zu geben.

Der Befehl ls (list) enthält eine Option zum rekursiven Auflisten. Dieser Befehl verfügt über viele Sortieroptionen, z. B. Liste nach Dateiname, Zugriffszeit, Größe usw., jedoch keine Klassifizierung, obwohl die Option -p Verzeichnisse beschriftet.

Jetzt könnte ich schreiben, z. B. ein Python-Skript genau das tun, was ich will. Aber find macht schon fast alles was ich will. Normalerweise ist es in einer Bash-Shell möglich, Programme so zu kombinieren, dass sie genau das machen, was Sie wollen: jedes Programm, wie find, , ls, wc, führt eine einfache Aufgabe durch, aber es funktioniert so gut. Nicht jedes Programm muss sortieren können, weil sort sortieren kann. Also, wirklich, ich bin nur neugierig ...

Meine Frage ist, wissen Sie, ob es einen Weg gibt zu tun, was ich will: sowohl Filter- und Sortier eine rekursive Dateiliste, nur durch Bash Programme zu kombinieren?

Zum Beispiel find gibt mir die Dateien in dieser, alphabetisch, Bestellung:

a.txt 
b\file1.txt 
b\subdir\file2.txt 
b\then_file3.txt 
c.txt 
d\file4.txt 
e.txt 

aber ich würde sie in dieser Reihenfolge bevorzugen, wo in jedem Verzeichnis, die normalen Dateien alphabetisch zuerst aufgeführt sind, durch die Verzeichnisse gefolgt, wieder in alphabetischer Reihenfolge:

a.txt 
c.txt 
e.txt 
b\file1.txt 
b\then_file3.txt 
b\subdir\file2.txt 
d\file4.txt 

(ich bin ein Windows-Benutzer, aber ich führe ein Bash-Shell in Cygwin.)

Danke.

Antwort

10

Verwenden Sie einen eingebetteten Suchvorgang. Der äußere Fund sucht alle Verzeichnisse und führt einen inneren finden, die nur die Dateien zeigt möchten, dass Sie in diesem Verzeichnis:

find . -type d -exec find {} -type f -maxdepth 1 \; 
+1

Dies funktioniert, gibt jedoch Warnungen aus. Sie können durch '-nowarn'-Option ausgeschaltet werden. –

+0

Danke! Ich dachte, es wäre wahrscheinlich irgendwie möglich. Also, meine SVN Filterung Beispiel wäre finden. -name '.svn' -prune -o -type d -exec find {} -type f -nowarn -maxdepth 1 \; – Rhubbarb

+1

Wenn ich dies versuche, ist das Ergebnis unsortiert (nach Verzeichnis und innerhalb von Verzeichnissen). –

1
tree -fi 

Auf Ubuntu und CentOS (und Red Hat, Fedora ...) es enthalten ist in seiner eigenes Paket, genannt "Baum" (duh). Ubuntu scheint dieses Paket nicht standardmäßig zu installieren, die anderen tun es.

EDIT: Sorry, habe nicht realisiert, dass Sie Cygwin verwenden. Nun, es wurde auch nach Cygwin portiert. Wenn es nicht im Standardsatz ist, see here.

+0

Sie können ein "-a" hinzufügen, um auch die versteckten Dateien zu erhalten. –

0

Sie haben nicht angegeben, wie Sie die Dinge handhaben möchten, wenn die Verzeichnisse mehr als eine Ebene tief gehen. Macht so etwas das, wonach Sie suchen?Es hat eine Breite-Erstnotiz innerhalb jeder Tiefe Ebene geordnet:

$for ((l = 0; l <= 24; l++)); do find . -mindepth ${l} -maxdepth ${l} -type f | sort; done 
+0

Das war schwer auszudrücken, also versuchte ich das im Beispiel zu illustrieren. Ich will nicht alle Dateien und dann alle Verzeichnisse (das ist einfach). Während ich in einem bestimmten Verzeichnis bin, möchte ich zunächst die Dateien auflisten und dann jedes Unterverzeichnis verarbeiten, das wiederum in jedem Verzeichnis rekursiv ist. – Rhubbarb

2

dieser Gruppe die Verzeichnisse innerhalb jeder Ebene zuerst, dann die Dateien und rekursiv in jedem Level und macht das gleiche:

ls -lR --group-directories-first 

Es steht jedoch auf dem Kopf von dem, was Sie wollten.