Verwenden Sie "locate" unter einem bestimmten Verzeichnis?

46

Ich habe mich gefragt, wie ich den Suchbereich von "locate" auf ein bestimmtes Verzeichnis beschränken kann.

Wie kann man beispielsweise Dateien / Verzeichnisse mit der Zeichenfolge "math" in ihren Namen unter einem Verzeichnis "/ home / tim / science /" finden?

Danke und Grüße!

Tim
quelle

Antworten:

30

UPDATE : Ein Hinweis zur Verwendung der Regex-Option von locate im Vergleich zur Dateinamenerweiterung der Shell in Bezug auf die Argumente von locate ...

ERWEITERUNG DES SHELL-DATEINAMENS
Bei der Eingabelocate /bin/b* (es gibt keine Anführungszeichen) passieren verschiedene Dinge.

  1. Erstens erweitert die Dateinamenerweiterung der Shell das spezielle Shell-Musterzeichen * (Dies liegt daran, dass das * ungeschützt ist, dh es gibt keine "doppelten Anführungszeichen").
  2. Diese resultierende Erweiterung ist eine Liste von Dateinamen . was vielleicht sehr lang ist ... Diese Liste wird an locatemöglichst viele einzelne Kommandozeilenargumente übergeben.
  3. locate testet dann jede dieser Argumente mit jeder der Dateien in seiner Datenbank und gibt Übereinstimmungen aus.

Beachten Sie jedoch, dass 'locate' kein Konzept für das aktuelle Arbeitsverzeichnis hat. Es werden nur Ihre Argumente mit den vollständig qualifizierten Dateinamen in der Datenbank verglichen.
Dies bedeutet, dass beide übereinstimmen, /bin/bash und /home/user/bin/brackets
Sie haben auf diese Weise einen gewissen Grad an Kontrolle, aber die Regex-Suche von locate bietet mehr. wie auch einige andere Optionen von locate.

LOCATE'S REGEX OPTION
Wenn Sie etwas locate -r "/bin/b.*"anderes eingeben , als mit einfachen Argumenten. ( Shell-expandierte Argumente sind nur eine Liste einfacher Argumente.)

  1. Die -rOption weist locate an, Ihr Argument als reguläres Muster zu behandeln.
  2. Die Anführungszeichen schützen das * vor der Dateinamenerweiterung der Shell. Es bedeutet, dass das * und der Punkt. sind jetzt spezielle Regex-Zeichen
  3. Als Regex können Sie 'locate' auf verschiedene Arten anweisen, mit seinem Datenbankeintrag übereinzustimmen: eg1. locate -r "^/bin/b.*"Erzeugt Dateinamen, die mit / bin / b ... eg2 beginnen. locate -r ~/"bin/b.*"Dateinamen beginnend mit produziert / home / user / bin / b .. Beachten Sie, dass die ~ / ist nicht durch „Anführungszeichen“ geschützt und unterliegt daher einer Tilde-Erweiterung Shell , das umwandelt ~ / in / home / user /

Zusammenfassung: "Shell-Dateinamenerweiterung" unterscheidet sich erheblich von "Regex"

Nun zurück zum ursprünglichen Beitrag:


locate listet normalerweise die gesamte Datenbank auf stdout auf. Um sie also auf ein bestimmtes Verzeichnis zu beschränken, müssen Sie sie filtern ... Sie können dies über die Optionen von locate tun.

Sie können die Regex-Funktion von locate verwenden, anstatt nur Shell-Globbing ... ( locate /dir/myfile* ist Shell-Globbing) ...

Von info lokalisieren : -r,--regex

  • "... (reguläre Ausdrücke) Übereinstimmungen werden für den gesamten Pfadnamen ausgeführt, und daher wird standardmäßig ein Pfadname abgeglichen, wenn ein Teil davon mit dem angegebenen regulären Ausdruck übereinstimmt. Der reguläre Ausdruck verwendet möglicherweise ^ oder $ , um eine Übereinstimmung am zu verankern Anfang oder Ende eines Pfadnamens. "

Anmerkung: -i = Groß- / Kleinschreibung ignorieren
. . . . . -r = regulärer Ausdruck
. . . . . ~ / wird von der Shell zu / home / user erweitert (wenn ~ / nicht in Anführungszeichen steht)
. . . . . '\' (Strich + Leerzeichen; keine Anführungszeichen) ist ein wörtliches Leerzeichen (um die Erweiterung der Shell zu vermeiden). Sie können den String in Anführungszeichen setzen, aber achten Sie darauf, das ~ / außerhalb der Anführungszeichen zu lassen: ~/my\ regexoder-/"my regex"

z.B. locate -ir ~/".*"la\ bella\ vitaist dasselbe wie locate -ir ~/".*la bella vita"und durchsucht Ihr gesamtes Home-Verzeichnis nach "La Bella Vita", das überall vorkommt.

Sie können auch die Suche nur auf die Datei beschränken Namen , aber der Verwendung -boder --basename.. in diesem Fall die regex Start-of-line ^gilt nur für die Basisnamen ...

Ich finde mich am häufigsten mit locate -bir

PS .. Locateist so schnell, dass ich noch nie verwendet habe find... noch habe ich Nautilus-Suche verwendet (zu langsam)

Wenn Sie mit 'locate' nach etwas suchen, das neu hinzugefügt wurde, führen Sie einfach den Befehl aus sudo updatedb, um die locate-Datenbank zu aktualisieren. (Wenn Sie es jedoch neu hinzugefügt haben, wissen Sie wahrscheinlich, wo es sich befindet.)

Peter.O
quelle
13

Pipe es durch grep, so

$ locate less | grep ^/bin
/bin/bzless
/bin/less
/bin/lessecho
/bin/lessfile
/bin/lesskey
/bin/lesspipe
/bin/zless

Bearbeiten: Die andere Antwort ist besser, ich wusste nicht, dass Sie ein Muster übergeben können, um zu lokalisieren.

Adam Byrtek
quelle
@Adam .. Unterschätze deine Methode nicht. Es ist in Ordnung, aber Sie können locate's eigenes Regex verwenden, anstatt Piping zu grep. Die "andere" Methode, auf die Sie sich beziehen, verwendet kein Regex und verhält sich ganz anders. Ich habe einige Details zu den Unterschieden zu my hinzugefügt Antwort ...
Peter.O
2
weniger lokalisieren | grep ^ / bin ist viel schneller als locate -r ^ / bin / .* less, da locate less eine effiziente Suche nach dem Wort less ausführt und locate -r eine Regex-Operation für alle Einträge in locatedb ausführt
Marcel Valdez Orozco
@MarcelValdezOrozco Was ist "effiziente Suche nach dem Wort" und warum ist es schneller als Regex?
Flashrunner
@Flashrunner Da locateeine O(log(n))Suche beendet wird, locatedbwenn Sie eine nicht reguläre Suchabfrage eingeben, können Sie die reguläre Suchabfrage verwenden, grepum eine O(m)Suche über die bereits reduzierten Unterergebnisse durchzuführen . (n = Gesamtzahl der Einträge in locatedb[dh in allen Dateien Ihres Laufwerks], m = Anzahl der Einträge , die weniger mit Ihrer übereinstimmen locatedb), Gesamtlaufkomplexität: O(log(n)) + O(m)wobei m im Durchschnitt ist log(n), sodass Sie 2*O(log(n))im Gegensatz zu O(n)Ihrer Leistung erhalten eine Regex-Abfrage über alle Einträge in locatedb.
Marcel Valdez Orozco
@MarcelValdezOrozco Aber warum ist eine Nicht-Regex-Suche über db so, O(log(n))während eine Regex-Suche so ist O(n)? Die Anzahl der Einträge in db ist jeweils gleich. Ich denke, es ist Suchalgorithmus?
Flashrunner
8

Du kannst es benutzen. locate /rootpath/*filenamespecIch hatte es noch nie versucht, aber es scheint zu funktionieren. Um dein Beispiel zu machen, wäre eslocate /home/tim/science/*math*

Möglicherweise möchten Sie sich den findBefehl ansehen, anstatt sich locateum ein solches Verhalten zu kümmern . Die Syntax wäre find rootforsearch -name filenamepattern -print. In diesem Fall würde Ihr Beispiel erfordern, dass find /home/tim/science -name *math* -print.Nicht so schnell gesucht wird, wie es keine zu durchsuchende Datenbank gibt ... es durchsucht tatsächlich das Dateisystem. Es gibt viele Optionen, die Sie außer Drucken auch verwenden können, wenn Sie beabsichtigen, tatsächlich etwas mit der Datei zu tun.

Nerdfest
quelle
Dies ist die beste Antwort, da sie sich locateselbst nutzt (kein anderes Dienstprogramm wie erforderlich grep) und auf reguläre Ausdrücke verzichtet (was in diesem Fall nett, aber unnötig ist).
Tom
Dies funktioniert wirklich wie ein Zauber, den Sie verwenden können, um Dateien in bestimmten Verzeichnispfad zu suchen, dank @Nerdfest
amit_game
1

Für mich ist das bequemste

cd /home/tim/science
locate math | grep `pwd`
alex440
quelle
Hast du die Frage wirklich gelesen?
Tessaracter