Hier ist eine Möglichkeit, wie Sie es tun könnten ...
find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
Für mich hat diese Lösung bei einer Befehlsausführung mit find nicht funktioniert, ich weiß nicht wirklich warum, also ist meine Lösung
find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
Erklärung: dasselbe wie sampson-chen one mit den Zusätzen von
-prune - Ignoriere den fortschreitenden Pfad von ...
-o - Dann, wenn keine Übereinstimmung, die Ergebnisse drucken (die Verzeichnisse bereinigen und die verbleibenden Ergebnisse drucken)
18:12 $ mkdir a b c d e
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
gzip: . is a directory -- ignored
gzip: ./a is a directory -- ignored
gzip: ./b is a directory -- ignored
gzip: ./c is a directory -- ignored
./c/3: 0.0% -- replaced with ./c/3.gz
gzip: ./d is a directory -- ignored
./d/4: 0.0% -- replaced with ./d/4.gz
gzip: ./e is a directory -- ignored
./e/5: 0.0% -- replaced with ./e/5.gz
./e/a: 0.0% -- replaced with ./e/a.gz
./e/b: 0.0% -- replaced with ./e/b.gz
So können Sie das mit find
spezifizieren :
find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"
Erklärung:
find .
- Suche vom aktuellen Arbeitsverzeichnis starten (standardmäßig rekursiv)-type f
- Geben Siefind
an dass Sie nur Dateien in den Ergebnissen haben möchten-name "*_peaks.bed"
- Suchen Sie nach Dateien, deren Name auf_peaks.bed
endet! -path "./tmp/*"
- Alle Ergebnisse ausschließen, deren Pfad mit./tmp/
beginnt! -path "./scripts/*"
- Schließen Sie auch alle Ergebnisse aus, deren Pfad mit./scripts/
beginnt
Testen der Lösung:
$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"
./d/4
./c/3
./e/a
./e/b
./e/5
Du warst ziemlich nah dran, der -name
Option berücksichtigt nur den Basisnamen, wo als -path
berücksichtigt den gesamten Pfad =)
Verwenden Sie
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
oder
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
oder
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
Die Reihenfolge ist wichtig. Es wird von links nach rechts ausgewertet. Beginnen Sie immer mit dem Pfadausschluss.
Erklärung
Verwenden Sie nicht -not
(oder !
), um das gesamte Verzeichnis auszuschließen. Verwenden Sie -prune
.Wie im Handbuch erklärt:
−prune The primary shall always evaluate as true; it
shall cause find not to descend the current
pathname if it is a directory. If the −depth
primary is specified, the −prune primary shall
have no effect.
und im GNU find Handbuch:
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
In der Tat, wenn Sie -not -path "./pathname"
verwenden ,find wertet den Ausdruck für jeden Knoten unter "./pathname"
aus .
Suchausdrücke sind nur Bedingungsauswertungen.
\( \)
- Gruppenoperation (Sie können-path "./tmp" -prune -o -path "./scripts" -prune -o
verwenden , aber es ist ausführlicher).-path "./script" -prune
- wenn-path
true zurückgibt und ein Verzeichnis ist, geben Sie true für dieses Verzeichnis zurück und nicht steige hinein.-path "./script" ! -prune
- wird als(-path "./script") AND (! -prune)
ausgewertet . Es kehrt das „immer wahr“ von Prune in immer falsch zurück. Es vermeidet das Drucken von"./script"
als Streichholz.-path "./script" -prune -false
- seit-prune
gibt immer true zurück, Sie können es mit-false
verfolgen dasselbe zu tun wie!
.-o
- ODER-Operator. Wenn zwischen zwei Ausdrücken kein Operator angegeben ist, wird standardmäßig der AND-Operator verwendet.
Daher \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
wird erweitert zu:
[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
Der Druck ist hier wichtig, da er ohne expandiert wird zu:
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
wird von find hinzugefügt - deshalb müssen Sie es meistens nicht in Ihrem Ausdruck hinzufügen. Und seit -prune
true zurückgibt, werden "./script" und "./tmp" ausgegeben.
Bei den anderen ist es nicht nötig, da wir -prune
umgestellt haben um immer falsch zurückzugeben.
Hinweis:Sie können find -D opt expr 2>&1 1>/dev/null
verwenden um zu sehen, wie es optimiert und erweitert wird,
find -D search expr 2>&1 1>/dev/null
um zu sehen, welcher Pfad überprüft wird.