Wie finde ich in einer Reihe von Verzeichnissen eine Datei, deren Name eine bestimmte Zeichenfolge enthält, z. B. "abcde"?
Wie finde ich in einer Reihe von Verzeichnissen eine Datei, deren Name eine bestimmte Zeichenfolge enthält, z. B. "abcde"?
Antworten:
find
durchsucht eine Verzeichnisstruktur und gibt Ergebnisse basierend auf einem Glob zurück :
find /your/dir -name "*abcde*"
Durch Hinzufügen des -type f
Schalters werden Ihre Suchkriterien so verfeinert, dass nur Dateien zurückgegeben werden.
find /your/dir -type f -name "*abcde*"
Sie können auch andere Schalter einschließen -maxdepth 2
, um die Suche auf zwei Verzeichnisebenen unter der angegebenen zu beschränken.
Auf diese Weise können Sie einen umfangreichen, zielgerichteten Suchbefehl erstellen, der schnell genau das zurückgibt, was Sie benötigen.
man find
verfügt über eine Fülle von Details, einschließlich Aktionen -exec
zum Ausführen eines Befehls für die von zurückgegebenen Dateien find
und Optionen zur Verwendung regulärer Ausdrücke.
Verwenden Sie find :
find path-to-search -name '*abcde*'
Wenn es locate
Ihnen passt (es ist schnell, aber nur so gut wie der letzte Lauf von sudo updatedb
). Sie können locate
mit einer eigenen integrierten Regex-Funktion arbeiten ...
Hier ist ein parametergesteuertes Skript, mit dem Sie tun können, was Sie wollen. Nennen Sie es mit $ 1 als "abcde", nach dem Sie suchen, und mit nachfolgenden Parametern als Verzeichnissen:
#!/bin/bash
a=("$@"); r=''
for ((i=1;i<${#a[@]};i++)); do r="$r|${a[i]}"; done
locate --regex "(${r:1}).*/[^/]*${a[0]}[^/]*$"
Ein Beispielaufruf sieht folgendermaßen aus:
$ ./script_name 'z' "$HOME/bin/perl" "$HOME/type/stuff"
Wie von Jasonwryan vorgeschlagen , ist hier eine kommentierte Version des Skripts.
Beachten Sie, dass locate
immer vollqualifizierte Pfade ausgegeben werden.
#!/bin/bash
# Note: Do not use a trailing / for directory names
#
# Any of the args can be an extended regex pattern.
#
# Create an array `a` which contains "$1", "$2", "$3", etc... (ie. "$@")
# writing the $-args to an array like this (using quotes) solves
# any possible problem with embedded whitespace
a=("$@")
#
# Set up an empty string which is to be built into a regex pattern
# of all directroy names (or an appropriate regex pattern)
r=''
#
# Each regex pattern is to be an extended regex
# Each regex pattern is concatenated to the preceding one
# with the extended-regex 'or' operator |
#
# Step through the array, starting at index 1 (ie, $2),
# and build the 'regex-pattern' for the directories
for ((i=1;i<${#a[@]};i++)); do r="$r|${a[i]}"; done
#
# Run 'locate' with
# |the target file pattern $1 |
# |zero-to-| |preceded and followed by |
# |-many | |zero-to-many non-slash chars|
# |anything| | |‾‾‾‾‾‾‾‾‾‾‾‾
# ‾‾‾‾‾‾‾|| | |
locate --regex "(${r:1}).*/[^/]*${a[0]}[^/]*$"
# ________| | |
# |directory-regex| last
# | in brackets ()| slash
# |stripped of its|
# |leading "|" |
#
locate abcde | egrep "(dirA|dirB|dirC)"
für die Verzeichnisse dirA, dirB, dirC.
Oder 3 Suchbefehle.
-type f
,find
damit Sie nur Ergebnisse erhalten, bei denen es sich um Dateien handelt.find /your/dir -type f -name "*abcde*"