GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Verwenden Sie den Befehl find, aber schließen Sie Dateien in zwei Verzeichnissen aus

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 Sie find 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.


Linux
  1. Finden Sie Dateien und Verzeichnisse unter Linux mit dem Befehl find

  2. So finden Sie die wichtigsten Verzeichnisse und Dateien (Festplattenspeicherplatz) in Linux heraus

  3. Kopieren Sie Dateien und Verzeichnisse unter Linux

  4. Eine Liste von Verzeichnissen vom Unix-Suchbefehl ausschließen?

  5. So verwenden Sie den Linux-Befehl find zum Suchen von Dateien

Grep-Befehl in Linux (Text in Dateien suchen)

So verwenden Sie den cp-Befehl zum Kopieren von Dateien und Verzeichnissen

So verwenden Sie den SCP-Befehl zum Übertragen von Dateien

So schließen Sie ein Verzeichnis beim Suchen von Dateien in Linux aus

Finden Sie Dateien und Verzeichnisse unter Linux ganz einfach

Wie finde ich die platzraubendsten Verzeichnisse oder Dateien heraus?