Xargs/Anwendung: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
|||
Zeile 4: | Zeile 4: | ||
''find(1)'' gibt man bekannt, er möge mit ASCII-NUL beendete Zeichenketten ausgeben, und xargs, er möge solche erwarten | ''find(1)'' gibt man bekannt, er möge mit ASCII-NUL beendete Zeichenketten ausgeben, und xargs, er möge solche erwarten | ||
<syntaxhighlight lang="bash" highlight="1" line> | <syntaxhighlight lang="bash" highlight="1" line> | ||
find / -user toelpel -print0 | xargs -0 rm | find / -user toelpel -print0 | xargs -0 rm | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Eingabedatei als Parameter === | === Eingabedatei als Parameter === | ||
Sollen die Dateien verschoben werden, erwartet mv die Quelldateien als erstes, das Zielverzeichnis als letztes Argument. | Sollen die Dateien verschoben werden, erwartet mv die Quelldateien als erstes, das Zielverzeichnis als letztes Argument. | ||
Zeile 18: | Zeile 20: | ||
=== Beispiele=== | === Beispiele=== | ||
<syntaxhighlight lang="bash" highlight="1" line> | <syntaxhighlight lang="bash" highlight="1" line> | ||
find /tmp -name core -type f -print | xargs /bin/rm -f | find /tmp -name core -type f -print | xargs /bin/rm -f | ||
Zeile 31: | Zeile 34: | ||
; Achtung | ; Achtung | ||
* Die Verzeichnisstruktur wird dabei nicht wieder hergestellt. | * Die Verzeichnisstruktur wird dabei nicht wieder hergestellt. | ||
* Die Dateien landen wirklich alle in '''/tmp/klaus/test''' | * Die Dateien landen wirklich alle in '''/tmp/klaus/test''' | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . -uid 1001 -print | xargs -i mv {} /tmp/klaus/test | find . -uid 1001 -print | xargs -i mv {} /tmp/klaus/test | ||
</syntaxhighlight> | |||
* Wenn man eine Datei '''software.list''' mit den Namen von Paketen hat, die sich im Verzeichnis '''~/installation/''' befindet und die wie folgt aufgebaut ist alltray audacity avidemux azureus compizconfig-settings-manager | * Wenn man eine Datei '''software.list''' mit den Namen von Paketen hat, die sich im Verzeichnis '''~/installation/''' befindet und die wie folgt aufgebaut ist alltray audacity avidemux azureus compizconfig-settings-manager | ||
* kann man mit xargs -a ~/installation/software.list sudo apt-get install | * kann man mit xargs -a ~/installation/software.list sudo apt-get install | ||
Zeile 38: | Zeile 45: | ||
* Dabei werden bereits installierte Pakete übersprungen. | * Dabei werden bereits installierte Pakete übersprungen. | ||
* Möchte man mehrere Dateien herunterladen, aber die Geschwindigkeit der Server lastet die eigene Internetverbindung nicht aus, so kann man mit xargs einfach mehrere Instanzen benutzen. | * Möchte man mehrere Dateien herunterladen, aber die Geschwindigkeit der Server lastet die eigene Internetverbindung nicht aus, so kann man mit xargs einfach mehrere Instanzen benutzen. | ||
<syntaxhighlight lang="bash" highlight="1" line> | <syntaxhighlight lang="bash" highlight="1" line> | ||
xargs -a downloadlist -n 1 -P 4 wget | xargs -a downloadlist -n 1 -P 4 wget | ||
Zeile 52: | Zeile 60: | ||
* We don't usually care about the ''command-name'', so “X”, “dummy”, “”, or “'inline cmd'” is often used. | * We don't usually care about the ''command-name'', so “X”, “dummy”, “”, or “'inline cmd'” is often used. | ||
* Here's an example of efficiently copying found files to ''/tmp'', in a POSIX-compliant way. | * Here's an example of efficiently copying found files to ''/tmp'', in a POSIX-compliant way. | ||
find . -name '*.txt' -type f \ -exec sh -c 'exec cp -f "$@" /tmp' X '{}' + | find . -name '*.txt' -type f \ -exec sh -c 'exec cp -f "$@" /tmp' X '{}' + | ||
</syntaxhighlight> | |||
* Obvious, simple, and readable, isn't it? Perhaps not, but worth knowing since it is safe, portable, and efficient. | * Obvious, simple, and readable, isn't it? Perhaps not, but worth knowing since it is safe, portable, and efficient. | ||
Zeile 59: | Zeile 69: | ||
* Ihr habt vor ein paar Minuten eilig etwas gespeichert, habt aber den Namen der Datei und den Pfad sofort vergessen. | * Ihr habt vor ein paar Minuten eilig etwas gespeichert, habt aber den Namen der Datei und den Pfad sofort vergessen. | ||
* Irgendwo in eurem Homeordner, irgendein Name, vor ein paar Minuten... | * Irgendwo in eurem Homeordner, irgendein Name, vor ein paar Minuten... | ||
<syntaxhighlight lang="bash" highlight="1" line> | <syntaxhighlight lang="bash" highlight="1" line> | ||
find ~ -type f ! -path '*/.*' -mmin -10 -ls | find ~ -type f ! -path '*/.*' -mmin -10 -ls | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Die Optionen im Einzelnen | Die Optionen im Einzelnen | ||
* ~ -- rekursiv in meinem Homeordner | * ~ -- rekursiv in meinem Homeordner | ||
Zeile 78: | Zeile 90: | ||
* Im Ordner public_html alle HTML und PHP Dateien ausfindig machen, in denen ".mp3" erwähnt wird. | * Im Ordner public_html alle HTML und PHP Dateien ausfindig machen, in denen ".mp3" erwähnt wird. | ||
* Nur die Dateinamen ausgeben. | * Nur die Dateinamen ausgeben. | ||
find ~/public_html \( -name \*.html -o -name \*.php \) | xargs grep -l '.mp3' | find ~/public_html \( -name \*.html -o -name \*.php \) | xargs grep -l '.mp3' | ||
* Zu beachten: ( ) * müssen vor der Bash versteckt, also mit Backslash escaped werden. | * Zu beachten: ( ) * müssen vor der Bash versteckt, also mit Backslash escaped werden. | ||
* Andere Methode (-exec statt xargs), gleiches Ergebnis. | * Andere Methode (-exec statt xargs), gleiches Ergebnis. | ||
find ~/public_html \( -name \*.html -o -name \*.php \) -exec grep -l '.mp3' '{}' \+ | find ~/public_html \( -name \*.html -o -name \*.php \) -exec grep -l '.mp3' '{}' \+ | ||
* Zu beachten: -exec mit''' \+''' abschließen statt mit '''\; '''beschleunigt das Abarbeiten ungemein, weil dann mehrere grep Prozesse parallel gestartet werden (vgl. xargs). | * Zu beachten: -exec mit''' \+''' abschließen statt mit '''\; '''beschleunigt das Abarbeiten ungemein, weil dann mehrere grep Prozesse parallel gestartet werden (vgl. xargs). | ||
* Setzt eine halbwegs aktuelle Version von find voraus. | * Setzt eine halbwegs aktuelle Version von find voraus. | ||
Zeile 89: | Zeile 105: | ||
* Anderer Einsatzzweck: Plattenplatz wird knapp, wo sind die großen Dateien? | * Anderer Einsatzzweck: Plattenplatz wird knapp, wo sind die großen Dateien? | ||
* Also zum Beispiel: in meinem Homeordner alle Dateien, die größer als 500MB sind. | * Also zum Beispiel: in meinem Homeordner alle Dateien, die größer als 500MB sind. | ||
find ~ -size +500M | find ~ -size +500M | ||
* Alle Dateien/Ordner in meinem Homeordner finden, die nicht mir gehören: find ~ ! -user $( whoami ) -ls | * Alle Dateien/Ordner in meinem Homeordner finden, die nicht mir gehören: find ~ ! -user $( whoami ) -ls | ||
* Alle Dateien/Ordner in meinem Homeordner, die root gehören: find ~ -user root | * Alle Dateien/Ordner in meinem Homeordner, die root gehören: find ~ -user root | ||
* Alle Dateien/Ordner in meinem Homeordner, die die Rechte auf 777 gesetzt haben, | * Alle Dateien/Ordner in meinem Homeordner, die die Rechte auf 777 gesetzt haben, | ||
* also Lese/Schreib/Ausführrechte für alle haben, lange Ausgabe wie "ls -l". | * also Lese/Schreib/Ausführrechte für alle haben, lange Ausgabe wie "ls -l". | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find ~ -perm 777 -ls | find ~ -perm 777 -ls | ||
* Welche Art von Dateien (Mimetype) liegen im Ordner Documents, mit Rücksicht auf Dateien mit Leerzeichen im Namen, nur in diesem Ordner, keine Unterordner: find ~/Documents/ -maxdepth 1 -type f -print0 | xargs -0 file | |||
* Welche Art von Dateien (Mimetype) liegen im Ordner Documents, mit Rücksicht auf Dateien mit Leerzeichen im Namen, nur in diesem Ordner, keine Unterordner: | |||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find ~/Documents/ -maxdepth 1 -type f -print0 | xargs -0 file | |||
* Find sucht immer rekursiv, es sei denn, man schränkt mit "-maxdepth" die Tiefe ein. | * Find sucht immer rekursiv, es sei denn, man schränkt mit "-maxdepth" die Tiefe ein. | ||
* Die Liste ließe sich beliebig fortsetzen. | * Die Liste ließe sich beliebig fortsetzen. | ||
Zeile 105: | Zeile 130: | ||
=== Beispiel 2 === | === Beispiel 2 === | ||
Dateien im aktuellen Ordner und Unterordnern finden, deren Namen einem bestimmen Muster entsprechen: | Dateien im aktuellen Ordner und Unterordnern finden, deren Namen einem bestimmen Muster entsprechen: | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . -name "*.jpg" | find . -name "*.jpg" | ||
* Dateien finden, deren Namen nicht einem bestimmten Muster entsprechen: | * Dateien finden, deren Namen nicht einem bestimmten Muster entsprechen: | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . \! -name "*.jpg" | find . \! -name "*.jpg" | ||
* Dateien finden, deren Namen einem bestimmten Muster entsprechen und die einen bestimmten Text enthalten: | * Dateien finden, deren Namen einem bestimmten Muster entsprechen und die einen bestimmten Text enthalten: | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . -name "*.php" -exec grep -il "suchtext" {} \; | find . -name "*.php" -exec grep -il "suchtext" {} \; | ||
* Dateien finden, die bestimmte Datei-Endungen haben (Mit Regular-Expressions finden): | * Dateien finden, die bestimmte Datei-Endungen haben (Mit Regular-Expressions finden): | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . -regex ".*(php|html|tpl)$" | find . -regex ".*(php|html|tpl)$" | ||
* Große Dateien finden (Dateien finden, die größer als ca. 500 MB sind): | * Große Dateien finden (Dateien finden, die größer als ca. 500 MB sind): | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . -type f -size +500000k -exec ls -lh {} \; | find . -type f -size +500000k -exec ls -lh {} \; | ||
* Dateien finden, deren Pfade einem bestimmten Pattern entsprechen: | * Dateien finden, deren Pfade einem bestimmten Pattern entsprechen: | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . -path "*/.svn*" | find . -path "*/.svn*" | ||
* Dateien finden, deren Pfade nicht einem bestimmten Pattern entsprechen: | * Dateien finden, deren Pfade nicht einem bestimmten Pattern entsprechen: | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . \! -path "*/.svn*" | find . \! -path "*/.svn*" | ||
* Dateien finden, die nicht einem bestimmten User (nicht root) gehören: | * Dateien finden, die nicht einem bestimmten User (nicht root) gehören: | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . \! -user root | find . \! -user root | ||
* Dateien finden, die “oo” oder “ee” im Namen haben: | * Dateien finden, die “oo” oder “ee” im Namen haben: | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . \( -name "*oo*" -or -name "*ee*" \) | find . \( -name "*oo*" -or -name "*ee*" \) | ||
* Dateien finden, die nicht “oo” oder “ee” im Namen haben: | * Dateien finden, die nicht “oo” oder “ee” im Namen haben: | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . \! \( -name "*oo*" -or -name "*ee*" \) | find . \! \( -name "*oo*" -or -name "*ee*" \) | ||
* Geht nicht mit find (GNU findutils) 4.4.2: ''' | * Geht nicht mit find (GNU findutils) 4.4.2: ''' | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find . -regex “.*(php|html|tpl)$”''' mkdir /tmp/tst cd /tmp/tst mkdir -p 1/2/3 mkdir -p 4/5/6 touch la.php touch 1/2/uu.tpl touch 4/lala.html touch 4/5/6/eee.php touch 4/5/oooooo' find . -regex “.*(php|html|tpl)$” | find . -regex “.*(php|html|tpl)$”''' mkdir /tmp/tst cd /tmp/tst mkdir -p 1/2/3 mkdir -p 4/5/6 touch la.php touch 1/2/uu.tpl touch 4/lala.html touch 4/5/6/eee.php touch 4/5/oooooo' find . -regex “.*(php|html|tpl)$” | ||
* es wird nix ausgegeben :( | * es wird nix ausgegeben :( | ||
Zeile 137: | Zeile 193: | ||
* Denken Sie daran, dass in diesem Beispiel beide Verzeichnisse auf dem selben Dateisystem sein müssen! | * Denken Sie daran, dass in diesem Beispiel beide Verzeichnisse auf dem selben Dateisystem sein müssen! | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 -exec ln {} /home/httpd/obsolete \; | find \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 -exec ln {} /home/httpd/obsolete \; | ||
* Gut, das hier ist etwas komplex und verlangt nach Erklärung. | * Gut, das hier ist etwas komplex und verlangt nach Erklärung. | ||
* Das Suchkriterium ist Folgendes: \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 | * Das Suchkriterium ist Folgendes: \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 | ||
Zeile 154: | Zeile 213: | ||
* Da Sie die Dateien von verschiedenen Quellen haben, haben Sie die Endungen ''jpg'', ''jpeg'', ''JPG'' oder ''JPEG''. | * Da Sie die Dateien von verschiedenen Quellen haben, haben Sie die Endungen ''jpg'', ''jpeg'', ''JPG'' oder ''JPEG''. | ||
* Sie möchten nicht im Verzeichnis ''old'' suchen, Sie möchten diese Liste zugeschickt bekommen und Ihr Benutzername ist ''john'': | * Sie möchten nicht im Verzeichnis ''old'' suchen, Sie möchten diese Liste zugeschickt bekommen und Ihr Benutzername ist ''john'': | ||
<syntaxhighlight lang="bash" highlight="1" line> | |||
find /shared/images -cnewer \ /shared/images/stamp \ -a -iregex ".*\.jpe?g" \ -a -not -regex ".*/old/.*" \ | mail john -s "Neue Images" | find /shared/images -cnewer \ /shared/images/stamp \ -a -iregex ".*\.jpe?g" \ -a -not -regex ".*/old/.*" \ | mail john -s "Neue Images" | ||
* Nun wäre es nicht sehr schön, dieses Kommando regelmäßig neu eingeben zu müssen, also brauchen Sie…? | * Nun wäre es nicht sehr schön, dieses Kommando regelmäßig neu eingeben zu müssen, also brauchen Sie…? | ||
=== Problembehebung === | === Problembehebung === |
Version vom 23. Dezember 2024, 13:57 Uhr
Dateinamen mit Leerzeichen
Üblicher Weise enthält der IFS das Leerzeichen, daher bricht xargs die Dateinamen dort auseinander.
- Dem ist abzuhelfen, wenn man die GNU-Version der benutzten Tools (find und xargs) verwendet.
find(1) gibt man bekannt, er möge mit ASCII-NUL beendete Zeichenketten ausgeben, und xargs, er möge solche erwarten
find / -user toelpel -print0 | xargs -0 rm
Eingabedatei als Parameter
Sollen die Dateien verschoben werden, erwartet mv die Quelldateien als erstes, das Zielverzeichnis als letztes Argument.
- Dieses Problem löst man bei xargs(1) genauso wie bei
find / -user toelpel -print0 | xargs -0 mv {} /tmp/toelpel-trash
Die Zeichenkombination "{}" zeigt dem xargs(1), an welcher Stelle er die Argumentliste für das Kommando einzufügen hat.
Beispiele
find /tmp -name core -type f -print | xargs /bin/rm -f
Finde Dateien mit dem Namen core in oder unterhalb des Verzeichnisses /tmp und lösche diese.
- Achtung, diese Aktion schlägt fehl falls die Dateinamen Zeilenvorschübe, einfache oder doppelte Anführungszeichen oder Leerzeichen enthalten.
- Mit folgendem Befehl werden alle Dateien aus dem aktuellen Verzeichnis entfernt, die auf das Muster *.tmp</nowiki> passen.
- Dabei werden Dateien, deren Namen Leerzeichen enthalten ebenfalls berücksichtigt: find . -name "*.tmp" -print0 | xargs -0 rm
- Als nächstes eine Anwendung mit der Ersatz-Zeichenkette {}.
- Alle Dateien des Benutzers mit der uid 1001 werden nach /tmp/klaus/test verschoben.
- Achtung
- Die Verzeichnisstruktur wird dabei nicht wieder hergestellt.
- Die Dateien landen wirklich alle in /tmp/klaus/test
find . -uid 1001 -print | xargs -i mv {} /tmp/klaus/test
- Wenn man eine Datei software.list mit den Namen von Paketen hat, die sich im Verzeichnis ~/installation/ befindet und die wie folgt aufgebaut ist alltray audacity avidemux azureus compizconfig-settings-manager
- kann man mit xargs -a ~/installation/software.list sudo apt-get install
- die Pakete komfortabel alle auf einmal installieren.
- Dabei werden bereits installierte Pakete übersprungen.
- Möchte man mehrere Dateien herunterladen, aber die Geschwindigkeit der Server lastet die eigene Internetverbindung nicht aus, so kann man mit xargs einfach mehrere Instanzen benutzen.
xargs -a downloadlist -n 1 -P 4 wget
- Dieser Befehl übergibt jeweils eine URL aus der Datei downloadlist an wget.
- Dabei wird wget vier mal jeweils mit einer anderen Datei gestartet.
- So werden vier Dateien auf einmal heruntergeladen und die Internetverbindung optimal ausgenutzt.
Weitere Möglichkeiten
This command is equivalent to using find with xargs, only a bit shorter and more efficient.
- But this form of ‑exec can be combined with a shell feature to solve the other problem (names with spaces).
- The POSIX shell allows us to use: sh -c command-line [ command-name [ args... ] ]
- We don't usually care about the command-name, so “X”, “dummy”, “”, or “'inline cmd'” is often used.
- Here's an example of efficiently copying found files to /tmp, in a POSIX-compliant way.
find . -name '*.txt' -type f \ -exec sh -c 'exec cp -f "$@" /tmp' X '{}' +
</syntaxhighlight>
- Obvious, simple, and readable, isn't it? Perhaps not, but worth knowing since it is safe, portable, and efficient.
Beispiel 1
Wo in meinem Homeordner liegt die Datei "test.pdf"? find ~ -name test.pdf
- Ihr habt vor ein paar Minuten eilig etwas gespeichert, habt aber den Namen der Datei und den Pfad sofort vergessen.
- Irgendwo in eurem Homeordner, irgendein Name, vor ein paar Minuten...
find ~ -type f ! -path '*/.*' -mmin -10 -ls
Die Optionen im Einzelnen
- ~ -- rekursiv in meinem Homeordner
- -type f -- eine Datei (kein Ordner...)
- ! -path '*/.*' -- ohne Dateien oder Ordner, die mit Punkt beginnen.
- -mmin -10 -- nicht älter als 10 Minuten
- -ls -- lange Anzeige (wie ls -l)
- Variante: mit Dotfiles, nicht aber Ordner, die mit Punkt beginnen (also ohne .gnome/ oder .kde/ und so weiter, aber mit .bash_history).
- Und zwar alle Dateien, die nicht älter als zwei Tage sind.
find ~ ! -path '*/.*/*' -type f -ctime -2
- Im Homeordner alle Dateien finden, deren Namen Leerzeichen enthalten.
- Wieder ohne Dateien oder Ordner, die mit Punkt beginnen.
find $HOME ! -path '*/.*' -type f -name '* *'
- $HOME -- ist gleichbedeutend mit ~ * -name '* *' -- Name enthält mindestens ein Leerzeichen
- Ganz ähnlich, aber diesmal wird nach Ordnern gesucht: find $HOME ! -path '*/.*' -type d -name '* *' -type d -- Ordner (type directory)
- Im Ordner public_html alle HTML und PHP Dateien ausfindig machen, in denen ".mp3" erwähnt wird.
- Nur die Dateinamen ausgeben.
find ~/public_html \( -name \*.html -o -name \*.php \) | xargs grep -l '.mp3'
- Zu beachten: ( ) * müssen vor der Bash versteckt, also mit Backslash escaped werden.
- Andere Methode (-exec statt xargs), gleiches Ergebnis.
find ~/public_html \( -name \*.html -o -name \*.php \) -exec grep -l '.mp3' '{}' \+
- Zu beachten: -exec mit \+ abschließen statt mit \; beschleunigt das Abarbeiten ungemein, weil dann mehrere grep Prozesse parallel gestartet werden (vgl. xargs).
- Setzt eine halbwegs aktuelle Version von find voraus.
- Hoppla, da sind auch Dateien mit Leerzeichen im Namen dabei? Kein Problem.
find ~/public_html \( -name \*.html -o -name \*.php \) -print0 | xargs -0 grep -l '.mp3'
- finds Option -print0 erzeugt die richtige Ausgabe für xargs Option -0
- Anderer Einsatzzweck: Plattenplatz wird knapp, wo sind die großen Dateien?
- Also zum Beispiel: in meinem Homeordner alle Dateien, die größer als 500MB sind.
find ~ -size +500M
- Alle Dateien/Ordner in meinem Homeordner finden, die nicht mir gehören: find ~ ! -user $( whoami ) -ls
- Alle Dateien/Ordner in meinem Homeordner, die root gehören: find ~ -user root
- Alle Dateien/Ordner in meinem Homeordner, die die Rechte auf 777 gesetzt haben,
- also Lese/Schreib/Ausführrechte für alle haben, lange Ausgabe wie "ls -l".
<syntaxhighlight lang="bash" highlight="1" line>
find ~ -perm 777 -ls
- Welche Art von Dateien (Mimetype) liegen im Ordner Documents, mit Rücksicht auf Dateien mit Leerzeichen im Namen, nur in diesem Ordner, keine Unterordner:
<syntaxhighlight lang="bash" highlight="1" line> find ~/Documents/ -maxdepth 1 -type f -print0 | xargs -0 file
- Find sucht immer rekursiv, es sei denn, man schränkt mit "-maxdepth" die Tiefe ein.
- Die Liste ließe sich beliebig fortsetzen.
- Wie vielseitig find ist, zeigt sich schon an der Länge der manpage.
- Find findet nach Name, Regular expression, Größe, Datum, Dateityp,...
- und so weiter und läßt sich mit "-exec" und der Pipe für "xargs" zu beinahe allem verwenden, was nur auf bestimmte Dateien/Ordner angewandt werden soll.
- Darum wird das Kommando in vielen Shellskripten verwendet.
Beispiel 2
Dateien im aktuellen Ordner und Unterordnern finden, deren Namen einem bestimmen Muster entsprechen:
<syntaxhighlight lang="bash" highlight="1" line>
find . -name "*.jpg"
- Dateien finden, deren Namen nicht einem bestimmten Muster entsprechen:
<syntaxhighlight lang="bash" highlight="1" line>
find . \! -name "*.jpg"
- Dateien finden, deren Namen einem bestimmten Muster entsprechen und die einen bestimmten Text enthalten:
<syntaxhighlight lang="bash" highlight="1" line>
find . -name "*.php" -exec grep -il "suchtext" {} \;
- Dateien finden, die bestimmte Datei-Endungen haben (Mit Regular-Expressions finden):
<syntaxhighlight lang="bash" highlight="1" line>
find . -regex ".*(php|html|tpl)$"
- Große Dateien finden (Dateien finden, die größer als ca. 500 MB sind):
<syntaxhighlight lang="bash" highlight="1" line>
find . -type f -size +500000k -exec ls -lh {} \;
- Dateien finden, deren Pfade einem bestimmten Pattern entsprechen:
<syntaxhighlight lang="bash" highlight="1" line>
find . -path "*/.svn*"
- Dateien finden, deren Pfade nicht einem bestimmten Pattern entsprechen:
<syntaxhighlight lang="bash" highlight="1" line>
find . \! -path "*/.svn*"
- Dateien finden, die nicht einem bestimmten User (nicht root) gehören:
<syntaxhighlight lang="bash" highlight="1" line>
find . \! -user root
- Dateien finden, die “oo” oder “ee” im Namen haben:
<syntaxhighlight lang="bash" highlight="1" line>
find . \( -name "*oo*" -or -name "*ee*" \)
- Dateien finden, die nicht “oo” oder “ee” im Namen haben:
<syntaxhighlight lang="bash" highlight="1" line>
find . \! \( -name "*oo*" -or -name "*ee*" \)
- Geht nicht mit find (GNU findutils) 4.4.2:
<syntaxhighlight lang="bash" highlight="1" line>
find . -regex “.*(php|html|tpl)$” mkdir /tmp/tst cd /tmp/tst mkdir -p 1/2/3 mkdir -p 4/5/6 touch la.php touch 1/2/uu.tpl touch 4/lala.html touch 4/5/6/eee.php touch 4/5/oooooo' find . -regex “.*(php|html|tpl)$”
- es wird nix ausgegeben :(
Beispiel 3
Angenommen, Sie möchten eine Liste der Verzeichnisse in /usr/share erhalten, dann tippen Sie: find /usr/share -type d
- Angenommen, Sie haben einen HTTP-Server und alle Ihre HTML-Dateien befinden sich in /home/httpd/html, wo Sie sich auch gerade befinden.
- Sie möchten eine Liste aller Dateien, deren Inhalt seit einem Monat nicht verändert worden ist.
- Da die Seiten von verschiedenen Schreibern stammen, enden einige auf html und einige auf htm.
- Sie möchten diese Dateien in das Verzeichnis /home/httpd/obsolete verknüpfen.
- Geben Sie folgendes ein:[
- Denken Sie daran, dass in diesem Beispiel beide Verzeichnisse auf dem selben Dateisystem sein müssen!
<syntaxhighlight lang="bash" highlight="1" line>
find \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 -exec ln {} /home/httpd/obsolete \;
- Gut, das hier ist etwas komplex und verlangt nach Erklärung.
- Das Suchkriterium ist Folgendes: \( -name "*.htm" -o -name "*.html" \) -a -ctime -30
- Es findet alle Dateien, die entweder auf .htm oder auf .html enden (( -name "*.htm" -o -name "*.html" )) und (-a) die in den letzten 30 Tagen nicht modifiziert wurden (-ctime -30).
- Beachten Sie die Klammern, die hier notwendig sind, da -a eine höhere Wertigkeit hat.
- Ließen Sie sie weg, würde das Kommando alle Dateien mit der Endung .htm finden sowie die Dateien, die auf .html enden und seit einem Monat nicht modifiziert wurden.
- Beachten Sie auch, dass die Klammern vor der Shell geschützt wurden.
- Gäben Sie ( .. ) anstelle von \( .. \) ein, würde die Shell versuchen, diese zu interpretieren und das Kommando -name "*.htm" -o -name "*.html" in einer Sub-Shell auszuführen.
- Sie können diesen Schutz übrigens auch durch Anführungszeichen erreichen.
- Und schließlich das Kommando, das für jede gefundene Datei ausgeführt wird: -exec ln {} /home/httpd/obsolete \;
- Auch hier müssen Sie das ;</nowiki> vor der Shell schützen, da diese es sonst als Kommandoseparator interpretiert und find sich beschweren wird, dass -exec ein Argument fehlt.
- Ein letztes Beispiel:
- Sie haben ein großes Verzeichnis mit allen möglichen Bilddateien: /shared/images.
- Normalerweise benutzen Sie touch, um den Zeitstempel einer Datei namens stamp in diesem Verzeichnis aufzufrischen, um eine Zeitreferenz zu haben.
- Sie wollen eine Liste aller JPEG-Dateien, die jünger als die Datei stamp sind.
- Da Sie die Dateien von verschiedenen Quellen haben, haben Sie die Endungen jpg, jpeg, JPG oder JPEG.
- Sie möchten nicht im Verzeichnis old suchen, Sie möchten diese Liste zugeschickt bekommen und Ihr Benutzername ist john:
<syntaxhighlight lang="bash" highlight="1" line>
find /shared/images -cnewer \ /shared/images/stamp \ -a -iregex ".*\.jpe?g" \ -a -not -regex ".*/old/.*" \ | mail john -s "Neue Images"
- Nun wäre es nicht sehr schön, dieses Kommando regelmäßig neu eingeben zu müssen, also brauchen Sie…?