Suchen Sie Dateien nach der Länge des Dateinamens


10

Ich möchte alle Dateien nach Länge der Dateinamen finden.

Zum Beispiel, wenn ich Dateien mit einer Länge von 1, wie zu finden a.go, b.go.

Ich setze:

grep '.\{1\}' file

Das geht aber nicht. Mit welchem ​​Befehl kann ich Dateien nach Dateinamenlänge suchen?


a.goist ein Dateiname der Länge 4. aist ein Dateiname der Länge 1. Dies ist Unix, nicht DOS, bei dem Name und Erweiterung getrennt waren und ein implizites Element .immer Teil des Dateinamens war.
Peter Cordes

Antworten:


3

grepsucht nach Mustern im Inhalt der Dateien. Wenn Sie sich die Namen der Dateien ansehen möchten , können Sie einfach einen Shell-Glob verwenden (wenn Sie nur Dateinamen im aktuellen Verzeichnis berücksichtigen möchten):

echo ?.go

(Übrigens ist es die Shell, die den Glob auswertet, nicht den echoBefehl.)

Wenn Sie rekursiv in Verzeichnissen suchen möchten, beginnend mit dem aktuellen Verzeichnis, müssen Sie Folgendes verwenden find:

find . -name '?.go'

(Beachten Sie, dass Sie das Muster in Anführungszeichen setzen müssen, um zu verhindern, dass die Shell es als Glob auswertet, bevor es findaufgerufen wird.)


1
Hier finden Sie auch Verzeichnisse, die auch dem Muster '? .Go' entsprechen.
slm

@slm, Verzeichnisse sind eine von vielen Dateitypen. Das OP hat nicht angegeben, nach welchem ​​Dateityp er gesucht hat.
Stéphane Chazelas

8

Wenn Sie nur die Dateinamen suchen möchten, können Sie den folgenden Befehl verwenden:

find -exec basename '{}' ';' | egrep '^.{100,}$'

Das wird ausgeführt find, wobei der Name der Datei oder des Verzeichnisses mit abgezogen wird basenameund dann nach einem Dateinamen oder Verzeichnisnamen mit mindestens 100 Zeichen gesucht wird. 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 suchen möchten, gehen Sie folgendermaßen vor:

find | egrep '/[^/]{100,}$'

Dadurch wird der Dateiname einschließlich des relativen Pfads zurückgegeben, zu dem Sie den Befehl find ausgeführt haben.


3

Beim grepDurchsuchen des Inhalts von Dateien wird zunächst nicht nach Dateinamen gesucht. Dafür willst du find. Es gibt keine Option zum Festlegen der Dateinamenlänge, aber Sie können die Ausgabe analysieren, um das zu erhalten, was Sie möchten. Hier sind einige Beispiele, die ich in einem Verzeichnis ausführe, das die folgenden Dateien enthält:

$ 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 sedBefehl entfernt nur das ./. Das -PFlag aktiviert Perl-kompatible reguläre Ausdrücke, für {n}die eine PCRE-Sache benötigt wird, und $bedeutet "Match the End of the String".

Sie können dies auch einfach tun:

find . -type f | grep -P '/...$'

Das ist in Ordnung für kleine Zahlen, die 15 Punkte eingeben, um mit Dateinamen der Länge 15 übereinzustimmen. Dies 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}\.'

Dies findet jedoch auch Dateien wie a.bo.go. Dies ist besser, wenn Ihre Dateinamen mehr als einen enthalten können .:

find . -type f | grep -P '/.{1}\.[^.]+$'

HINWEIS: Bei der obigen Lösung wird davon ausgegangen, dass Sie relativ gesunde Dateinamen haben, die keine neuen Zeilenzeichen usw. enthalten. Bei der Berechnung der Länge, die möglicherweise nicht Ihren Wünschen entspricht, werden auch Leerzeichen in Dateinamen nicht ignoriert. Wenn eines dieser Probleme vorliegt, lassen Sie es mich wissen und ich werde meine Antwort aktualisieren.


1

Sie geben nicht an, aber wenn sich die Dateien in einer Verzeichnisstruktur befinden, können Sie findDateien mit der Länge 1 mithilfe von Folgendem 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

Verwenden Sie unter MacOS X egrep und entfernen Sie die Option -P
Bart Kummel

@BartKummel - eigentlich benutze ich unter OSX ggrep: heystephenwood.com/2013/09/install-gnu-grep-on-mac-osx.html . Beachten Sie auch, dass dieses Q nicht als OSX markiert wurde, sodass die Verwendung von grepgeeignet ist.
slm

1

Ich würde so etwas benutzen.

find . -type f -name "?.go"

Also, wenn Sie zwei "?" dann suchen Sie nach Dateinamen mit zwei Zeichen und der Erweiterung.


0

Wenn Sie den regulären Ausdruck im Befehl find verwenden möchten, sollten Sie Folgendes verwenden "":

find /var/log -iname "*.err" 

für Ihren Fall verwenden:

find yourpath -type f -a -name "?.go"

Sie sollten Ihren realen Pfad durch Ihren Pfad ersetzen. Dies -abedeutet And -type f, dass Sie nur nach regulären Dateien suchen.

? In Ihrer Abfrage bedeutet ein Zeichen wie DOS, wenn Sie sich erinnern.


-1

ls ?.* sollte Ihnen die gewünschten Ergebnisse liefern.


Willkommen bei Unix.SE. Es ist leider nicht sinnvoll, Antworten auf alte Fragen hinzuzufügen, die bereits viele gute Antworten haben. (Es sei denn, es gibt einen neuen besseren Weg, um ein altes Problem zu lösen, oder Sie haben eine bessere Lösung als die alten Antworten.) Wenn Sie einige Fragen beantworten möchten, lesen Sie die neuen Fragen auf der Startseite.
Peter Cordes
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.