linux - tab - ubuntu terminal titel
So schließen Sie ein Verzeichnis in der Suche aus. Befehl (20)
Ich versuche, einen Suchbefehl für alle JavaScript-Dateien auszuführen, aber wie schließe ich ein bestimmtes Verzeichnis aus?
Hier ist der Suchcode, den wir verwenden.
for file in $(find . -name '*.js'); do java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file; done
Das funktioniert, weil TESTS die Dateien für das Muster " * foo * " finden:
find ! -path "dir1" ! -path "dir2" -name "*foo*"
aber es funktioniert nicht , wenn Sie kein Muster verwenden ( FIND überprüft die Datei nicht). So find
seine früher bewerteten " echten " & " falschen " Bools nicht. Beispiel für nicht funktionierenden Anwendungsfall mit obiger Schreibweise:
find ! -path "dir1" ! -path "dir2" -type f
Es gibt keine TESTS! Wenn Sie also Dateien ohne Mustererkennung suchen müssen, verwenden Sie -prune. Durch die Verwendung von Prune ist find
immer schneller, während es diese Verzeichnisse wirklich überspringt, anstatt es zu vergleichen oder besser nicht zu passen. Benutzen Sie in diesem Fall etwas wie:
find dir -not \( -path "dir1" -prune \) -not \( -path "dir2" -prune \) -type f
oder:
find dir -not \( -path "dir1" -o -path "dir2" -prune \) -type f
Grüße
Das ist für mich auf einem Mac geeignet:
find . -name *.php -or -path "./vendor" -prune -or -path "./app/cache" -prune
Es schließt vendor
und app/cache
Verzeichnis für den Suchnamen aus, der mit php
.
Dies ist das Format, das ich verwendet habe, um einige Pfade auszuschließen:
$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"
Ich habe damit alle Dateien gefunden, die nicht in ". *" Pfaden liegen:
$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
Dies ist der einzige, der für mich funktioniert hat.
Suche nach "NameOfFile" mit Ausnahme von "Directory". Betonen Sie die Sterne *.
find / -name NameOfFile ! -path '*/Directory/*'
Es gibt viele gute Antworten, ich brauchte nur etwas Zeit, um zu verstehen, wofür jedes Element des Befehls und die Logik dahinter standen.
find . -path ./misc -prune -o -name '*.txt' -print
find beginnt, Dateien und Verzeichnisse im aktuellen Verzeichnis zu finden, daher der find .
.
Die Option -o
steht für ein logisches ODER und trennt die beiden Teile des Befehls:
[ -path ./misc -prune ] OR [ -name '*.txt' -print ]
Jedes Verzeichnis oder jede Datei, die nicht das Verzeichnis ./misc ist , übergibt nicht den ersten -path ./misc
. Aber sie werden gegen den zweiten Ausdruck getestet werden. Wenn ihr Name dem Muster *.txt
sie wegen der Option -print
gedruckt.
Wenn find das Verzeichnis ./misc erreicht, erfüllt dieses Verzeichnis nur den ersten Ausdruck. Also wird die Option -prune
darauf angewendet. Es teilt dem Befehl find mit, dieses Verzeichnis nicht zu durchsuchen. So wird jede Datei oder jedes Verzeichnis in ./misc nicht einmal von find untersucht, wird nicht gegen den zweiten Teil des Ausdrucks getestet und nicht gedruckt.
Für FreeBSD Benutzer:
find . -name '*.js' -not -path '*exclude/this/dir*'
Für eine funktionierende Lösung (getestet auf Ubuntu 12.04 (Precise Pangolin)) ...
find ! -path "dir1" -iname "*.mp3"
sucht nach MP3-Dateien im aktuellen Ordner und in den Unterordnern mit Ausnahme des Verzeichnisses dir1.
Benutzen:
find ! -path "dir1" ! -path "dir2" -iname "*.mp3"
... um dir1 UND dir2 auszuschließen
Hier besteht eindeutig Verwirrung darüber, wie die bevorzugte Syntax zum Überspringen eines Verzeichnisses aussehen sollte.
GNU Meinung
To ignore a directory and the files under it, use -prune
Argumentation
-prune
stoppt beim Abstieg in ein Verzeichnis. -not -path
wird der -not -path
immer noch in das übersprungene Verzeichnis -not -path
, aber -not -path
ist immer falsch, wenn find
jede Datei testet.
Probleme mit -prune
-prune
macht, was es beabsichtigt, aber sind immer noch einige Dinge, um die Sie sich kümmern müssen, wenn Sie es verwenden.
find
druckt das bereinigte Verzeichnis.- WAHR Das ist beabsichtigtes Verhalten, es geht einfach nicht hinein. Um zu vermeiden, dass das Verzeichnis vollständig gedruckt wird, verwenden Sie eine Syntax, die es logisch auslässt.
-prune
funktioniert nur mit-print
und anderen Aktionen.- NICHT WAHR .
-prune
funktioniert mit allen Aktionen außer "-delete
. Warum funktioniert das nicht mit delete? Für-delete
zu arbeiten, muss das Verzeichnis in der DFS-Reihenfolge-delete
werden, da-delete
zuerst die Blätter, dann die Eltern der Blätter usw.-prune
Aber um-prune
sinnvoll zu definieren, mussfind
treffen Verzeichnis und stoppe absteigend, was bei-depth
oder-delete
eindeutig keinen Sinn-delete
.
- NICHT WAHR .
Performance
Ich habe einen einfachen Test der drei oben aufgewerteten Antworten zu dieser Frage eingerichtet (ersetzte -print
mit -exec bash -c 'echo $0' {} \;
um ein anderes Aktionsbeispiel -exec bash -c 'echo $0' {} \;
). Ergebnisse sind unten
----------------------------------------------
# of files/dirs in level one directories
.performance_test/prune_me 702702
.performance_test/other 2
----------------------------------------------
> find ".performance_test" -path ".performance_test/prune_me" -prune -o -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
[# of files] 3 [Runtime(ns)] 23513814
> find ".performance_test" -not \( -path ".performance_test/prune_me" -prune \) -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
[# of files] 3 [Runtime(ns)] 10670141
> find ".performance_test" -not -path ".performance_test/prune_me*" -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
[# of files] 3 [Runtime(ns)] 864843145
Fazit
Sowohl die Syntax von f10bit als auch die Syntax von Daniel C. Sobral benötigten im Durchschnitt 10-25ms. GetFree's Syntax , die -prune
nicht verwendet, dauerte 865ms. Also, das ist ein ziemlich extremes Beispiel, aber wenn Sie sich um die Laufzeit kümmern und etwas -prune
intensives tun, sollten Sie -prune
.
Beachten Sie, dass die Syntax von Daniel C. Sobral die bessere der beiden -prune
Syntaxen war; aber ich vermute stark, dass dies das Ergebnis von etwas Caching ist, da die Reihenfolge, in der die beiden rannten, zum entgegengesetzten Ergebnis führte, während die Nicht-Prune-Version immer am langsamsten war.
Testskript
#!/bin/bash
dir='.performance_test'
setup() {
mkdir "$dir" || exit 1
mkdir -p "$dir/prune_me/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/w/x/y/z" \
"$dir/other"
find "$dir/prune_me" -depth -type d -exec mkdir '{}'/{A..Z} \;
find "$dir/prune_me" -type d -exec touch '{}'/{1..1000} \;
touch "$dir/other/foo"
}
cleanup() {
rm -rf "$dir"
}
stats() {
for file in "$dir"/*; do
if [[ -d "$file" ]]; then
count=$(find "$file" | wc -l)
printf "%-30s %-10s\n" "$file" "$count"
fi
done
}
name1() {
find "$dir" -path "$dir/prune_me" -prune -o -exec bash -c 'echo "$0"' {} \;
}
name2() {
find "$dir" -not \( -path "$dir/prune_me" -prune \) -exec bash -c 'echo "$0"' {} \;
}
name3() {
find "$dir" -not -path "$dir/prune_me*" -exec bash -c 'echo "$0"' {} \;
}
printf "Setting up test files...\n\n"
setup
echo "----------------------------------------------"
echo "# of files/dirs in level one directories"
stats | sort -k 2 -n -r
echo "----------------------------------------------"
printf "\nRunning performance test...\n\n"
echo \> find \""$dir"\" -path \""$dir/prune_me"\" -prune -o -exec bash -c \'echo \"\$0\"\' {} \\\;
name1
s=$(date +%s%N)
name1_num=$(name1 | wc -l)
e=$(date +%s%N)
name1_perf=$((e-s))
printf " [# of files] $name1_num [Runtime(ns)] $name1_perf\n\n"
echo \> find \""$dir"\" -not \\\( -path \""$dir/prune_me"\" -prune \\\) -exec bash -c \'echo \"\$0\"\' {} \\\;
name2
s=$(date +%s%N)
name2_num=$(name2 | wc -l)
e=$(date +%s%N)
name2_perf=$((e-s))
printf " [# of files] $name2_num [Runtime(ns)] $name2_perf\n\n"
echo \> find \""$dir"\" -not -path \""$dir/prune_me*"\" -exec bash -c \'echo \"\$0\"\' {} \\\;
name3
s=$(date +%s%N)
name3_num=$(name3 | wc -l)
e=$(date +%s%N)
name3_perf=$((e-s))
printf " [# of files] $name3_num [Runtime(ns)] $name3_perf\n\n"
echo "Cleaning up test files..."
cleanup
Ich fand den Namen der Funktionen in C-Quellen-Dateien auszuschließen * .o und auszuschließen * .swp und auszuschließen (nicht reguläre Datei) und Dir-Ausgabe mit diesem Befehl ausschließen:
find . \( ! -path "./output/*" \) -a \( -type f \) -a \( ! -name '*.o' \) -a \( ! -name '*.swp' \) | xargs grep -n soc_attach
Ich finde das Folgende leichter zu verstehen als andere vorgeschlagene Lösungen:
find build -not \( -path build/external -prune \) -name \*.js
Das kommt von einem tatsächlichen Anwendungsfall, bei dem ich Yui-Compressor für einige von Wintersmith erzeugte Dateien aufrufen musste, aber andere Dateien weglassen musste, die unverändert gesendet werden mussten.
Inside \(
und \)
ist ein Ausdruck, der exakt mit build/external
übereinstimmt und bei Erfolg vermeidet, etwas darunter zu durchlaufen . Dies wird dann als einzelner Ausdruck mit der Escape-Klammer gruppiert und mit dem Präfix -not
was dazu führt, find
alles -not
wird, was mit diesem Ausdruck übereinstimmt.
Man könnte fragen, ob das Hinzufügen -not
alle anderen Dateien, die durch -prune
versteckt sind, -prune
, und die Antwort ist nein. Die Art -prune
Weise, wie -prune
funktioniert, ist, dass alle Dateien, die unter diesem Verzeichnis liegen, permanent ignoriert werden.
Dies ist auch einfach erweiterbar, um zusätzliche Ausschlüsse hinzuzufügen. Beispielsweise:
find build -not \( -path build/external -prune \) -not \( -path build/blog -prune \) -name \*.js
Ich habe die Vorschläge auf dieser Seite gefunden und viele andere Seiten funktionieren auf meinem Mac OS X System nicht. Ich habe jedoch eine Variation gefunden, die für mich funktioniert.
Die große Idee ist, den Macintosh HD zu durchsuchen, aber zu vermeiden, alle externen Volumes zu durchlaufen, die meistens Time Machine-Backups, Imagesicherungen, gemountete Freigaben und Archive sind, ohne sie alle unmounten zu müssen, was oft unpraktisch ist.
Hier ist mein Arbeitsskript, das ich "findit" genannt habe.
#!/usr/bin/env bash
# inspired by http://.com/questions/4210042/exclude-directory-from-find-command Danile C. Sobral
# using special syntax to avoid traversing.
# However, logic is refactored because the Sobral version still traverses
# everything on my system
echo ============================
echo find - from cwd, omitting external volumes
date
echo Enter sudo password if requested
sudo find . -not \( \
-path ./Volumes/Archive -prune -o \
-path ./Volumes/Boot\ OS\ X -prune -o \
-path ./Volumes/C \
-path ./Volumes/Data -prune -o \
-path ./Volumes/jas -prune -o \
-path ./Volumes/Recovery\ HD -prune -o \
-path ./Volumes/Time\ Machine\ Backups -prune -o \
-path ./Volumes/SuperDuper\ Image -prune -o \
-path ./Volumes/userland -prune \
\) -name "$1" -print
date
echo ============================
iMac2:~ jas$
Die verschiedenen Pfade haben mit externen Archiv-Volumes, Time Machine, virtuellen Maschinen, anderen gemounteten Servern und so weiter zu tun. Einige der Volume-Namen enthalten Leerzeichen.
Ein guter Testlauf ist "findit index.php", da diese Datei an vielen Stellen auf meinem System vorkommt. Mit diesem Skript dauert es ungefähr 10 Minuten, um die Hauptfestplatte zu durchsuchen. Ohne diese Ausnahmen dauert es viele Stunden.
Ich habe mit find
eine Liste von Dateien für xgettext
und wollte ein bestimmtes Verzeichnis und seinen Inhalt weglassen. Ich habe viele Permutationen von -path
kombiniert mit -prune
, konnte aber das Verzeichnis, das ich -prune
, nicht vollständig ausschließen.
Obwohl ich in der Lage war, den Inhalt des Verzeichnisses zu ignorieren, das ich ignorieren wollte, gab find
dann das Verzeichnis selbst als eines der Ergebnisse zurück, was dazu xgettext
, dass xgettext
abstürzte (akzeptiert keine Verzeichnisse; nur Dateien).
Meine Lösung war einfach grep -v
zu verwenden, um das Verzeichnis zu überspringen, das ich nicht in den Ergebnissen wollte:
find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext
Ob es ein Argument für das find
, das 100% funktioniert, kann ich nicht mit Sicherheit sagen. Die Verwendung von grep
war eine schnelle und einfache Lösung nach einigen Kopfschmerzen.
Keine der vorherigen Antworten ist gut auf Ubuntu. Versuche dies:
find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"
Ich habe das here
Sie können die Option "Bereinigen" verwenden, um dies zu erreichen. Wie in zum Beispiel:
find ./ -path ./beta/* -prune -o -iname example.com -print
Oder die umgekehrte grep "grep -v" -Option:
find -iname example.com | grep -v beta
Sie können detaillierte Anweisungen und Beispiele im Linux-Suchbefehl finden und Verzeichnisse von der Suche ausschließen .
Verwenden Sie besser die exec
Aktion als die for
Schleife:
find . -path "./dirtoexclude" -prune \
-o -exec java -jar config/yuicompressor-2.4.2.jar --type js '{}' -o '{}' \;
Die exec ... '{}' ... '{}' \;
wird für jede übereinstimmende Datei einmal ausgeführt und ersetzt die Klammern '{}'
durch den aktuellen Dateinamen.
Beachten Sie, dass die geschweiften Klammern in einfache Anführungszeichen eingeschlossen sind, um sie vor einer Interpunktion als Shell-Skript-Interpunktion zu schützen * .
Anmerkungen
* Im Abschnitt Beispiele der find (GNU findutils) 4.4.2
man page
Verwenden Sie den Prune-Schalter, wenn Sie zum Beispiel das misc
Verzeichnis ausschließen möchten, fügen -path ./misc -prune -o
einfach einen -path ./misc -prune -o
zu Ihrem find-Befehl hinzu:
find . -path ./misc -prune -o -name '*.txt' -print
Hier ist ein Beispiel mit mehreren Verzeichnissen:
find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -prune -o -print
Hier schließen wir dir1, dir2 und dir3 aus, da es in find
Ausdrücken eine Aktion ist, die auf das Kriterium -path dir1 -o -path dir2 -o -path dir3
(wenn dir1 oder dir2 oder dir3) wirkt, mit dem type -d
UND-verknüpft . Weitere Aktion ist -o print
, nur drucken.
Wenn -prune
nicht für Sie funktioniert, wird dies:
find -name "*.js" -not -path "./directory/*"
Wenn Suchverzeichnisse Muster haben (in meinem Fall meistens); Sie können es einfach wie folgt tun:
find ./n* -name "*.tcl"
Im obigen Beispiel; Es sucht in allen Unterverzeichnissen, die mit "n" beginnen.
how-to-use-prune-option-of-find-in-sh ist eine ausgezeichnete Antwort von Laurence Gonsalves auf die Funktionsweise von -prune
.
Und hier ist die generische Lösung:
find /path/to/search \
-type d \
\( -path /path/to/search/exclude_me \
-o \
-name exclude_me_too_anywhere \
\) \
-prune \
-o \
-type f -name '*\.js' -print
Um das Eingeben von /path/to/seach/
mehrmals zu vermeiden, wickeln Sie den find
in ein pushd .. popd
Paar.
pushd /path/to/search; \
find . \
-type d \
\( -path ./exclude_me \
-o \
-name exclude_me_too_anywhere \
\) \
-prune \
-o \
-type f -name '*\.js' -print; \
popd
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -prune