Ich möchte alle Dateien anhand der Länge der Dateinamen finden.
Wenn ich beispielsweise Dateien der Länge 1 suchen möchte, wie a.go
, b.go
.
Ich lege:
grep '.\{1\}' file
Aber das funktioniert nicht. Mit welchem Befehl kann ich Dateien anhand der Dateinamenlänge suchen?
Antwort1
Wenn Sie nur die Dateinamen finden möchten, können Sie den folgenden Befehl verwenden:
find -exec basename '{}' ';' | egrep '^.{100,}$'
Dadurch wird ausgeführt find
, der Name der Datei oder des Verzeichnisses wird mithilfe von abgerufen basename
und dann nach einem beliebigen Datei- oder Verzeichnisnamen gesucht, der mindestens 100 Zeichen lang ist. Wenn Sie einen Dateinamen mit einer genauen Länge suchen möchten, verwenden Sie {100}
anstelle von {100,}
.
Wenn Sie die Dateinamen einschließlich des Pfads finden möchten, gehen Sie wie folgt vor:
find | egrep '/[^/]{100,}$'
Dadurch wird der Dateiname einschließlich des relativen Pfads zu dem Ort zurückgegeben, an dem Sie den Suchbefehl ausgeführt haben.
Antwort2
grep
sucht nach Mustern im Inhalt der Dateien. Wenn Sie sich dieNamender Dateien können Sie einfach einen Shell-Glob verwenden (wenn Sie nur die Dateinamen im aktuellen Verzeichnis berücksichtigen möchten):
echo ?.go
(Übrigens ist es die Shell, die den Glob auswertet, nicht der echo
Befehl.)
Wenn Sie rekursiv in Verzeichnissen suchen möchten, beginnend mit dem aktuellen Verzeichnis, verwenden Sie das folgende Tool find
:
find . -name '?.go'
(Beachten Sie, dass Sie das Muster in Anführungszeichen setzen müssen, um zu verhindern, dass die Shell es vor dem Aufruf als Glob auswertet find
.)
Antwort3
Zunächst grep
durchsucht man dieInhaltvon Dateien, es wird nicht nach Dateinamen gesucht. Dafür brauchen Sie find
. Es gibt keine Option zum Festlegen der Dateinamenlänge, aber Sie können die Ausgabe analysieren, um das Gewünschte zu erhalten. Hier sind einige Beispiele, die ich in einem Verzeichnis mit den folgenden Dateien ausführe:
$ tree
.
├── a
├── ab
├── abc
├── abcd
└── dir
├── a
├── ab
├── abc
└── abcd
Die Suche nach Dateien in diesem Verzeichnis gibt Folgendes zurück:
$ find . -type f | sort
./a
./ab
./abc
./abcd
./dir/a
./dir/ab
./dir/abc
./dir/abcd
Um also die Dateien mit einer Länge von X zu finden, müssen wir den Pfad entfernen und nur die Zeichen nach dem letzten abgleichen /
:
$ find . -type f | grep -P '/.{3}$'
Der sed
Befehl entfernt einfach das ./
. Das -P
Flag aktiviert Perl-kompatible reguläre Ausdrücke, die für {n}
PCRE erforderlich sind und $
„das Ende der Zeichenfolge abgleichen“ bedeuten.
Sie können auch einfach Folgendes tun:
find . -type f | grep -P '/...$'
Bei kleinen Zahlen ist das kein Problem, aber die Eingabe von 15 Punkten zum Abgleichen von Dateinamen mit der Länge 15 ist nicht sehr effizient.
Wenn Sie die Erweiterung ignorieren und nur den Dateinamen abgleichen möchten, gehen Sie wie folgt vor (wie von @slm vorgeschlagen):
find . -type f | grep -P '/.{1}\.'
Allerdings werden dadurch auch Dateien wie gefunden a.bo.go
. Dies ist besser, wenn Ihre Dateinamen mehr als ein enthalten können .
:
find . -type f | grep -P '/.{1}\.[^.]+$'
HINWEIS: Die obige Lösung geht davon aus, dass Sie relativ vernünftige Dateinamen haben, die keine Zeilenumbruchzeichen usw. enthalten. Außerdem werden bei der Berechnung der Länge keine Leerzeichen in Dateinamen ignoriert, was möglicherweise nicht Ihren Wünschen entspricht. Wenn eines davon ein Problem darstellt, lassen Sie es mich wissen und ich werde meine Antwort aktualisieren.
Antwort4
Sie geben nichts an, aber wenn sich die Dateien in einer Verzeichnisstruktur befinden, können Sie find
Dateien der Länge 1 mithilfe von suchen grep
:
$ find . -type f | grep -P '/.{1}\.'
Beispiel
$ find . -type f | grep -P '/.{1}\.' | head -10
./util-linux-2.19/include/c.h
./88366/a.bash
./89186/a.bash
./89563/b.txt
./89563/a.txt
./89563/c.txt
./89563/d.txt
./91734/2.c
./91734/4.c
./91734/1.c