Xargs: Unterschied zwischen den Versionen

Aus Foxwiki
K Textersetzung - „Man-Pages“ durch „Man-Page“
 
(18 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
{{DISPLAYTITLE:xargs}}
'''xargs''' erstellt Befehlszeilen von der Standardeingabe und führt sie aus
'''xargs''' erstellt Befehlszeilen von der Standardeingabe und führt sie aus


Zeile 77: Zeile 79:
|-
|-
|}
|}
= Konfiguration =
== Dateien ==


= Anwendungen =
= Anwendungen =
= Dokumentation =
== Man-Pages ==
# XARGS(1) General Commands Manual
== Info-Pages ==
= Links =
== Intern ==
== Weblinks ==
= Testfragen =
<div class="toccolours mw-collapsible mw-collapsed">
''Testfrage 1''
<div class="mw-collapsible-content">'''Antwort1'''</div>
</div>
<div class="toccolours mw-collapsible mw-collapsed">
''Testfrage 2''
<div class="mw-collapsible-content">'''Antwort2'''</div>
</div>
<div class="toccolours mw-collapsible mw-collapsed">
''Testfrage 3''
<div class="mw-collapsible-content">'''Antwort3'''</div>
</div>
<div class="toccolours mw-collapsible mw-collapsed">
''Testfrage 4''
<div class="mw-collapsible-content">'''Antwort4'''</div>
</div>
<div class="toccolours mw-collapsible mw-collapsed">
''Testfrage 5''
<div class="mw-collapsible-content">'''Antwort5'''</div>
</div>
=  TMP =
===  Dateinamen mit Leerzeichen ===
===  Dateinamen mit Leerzeichen ===
Üblicher Weise enthält der IFS das Leerzeichen, daher bricht ''xargs ''die Dateinamen dort auseinander.  
Ü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
* 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 ===
===  Eingabedatei als Parameter ===
Zeile 124: Zeile 93:


===  Beispiele===
===  Beispiele===
find /tmp -name core -type f -print | xargs /bin/rm -f
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.  
* 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.  
* Achtung, diese Aktion schlägt fehl falls die Dateinamen Zeilenvorschübe, einfache oder doppelte Anführungszeichen oder Leerzeichen enthalten.  
Zeile 135: Zeile 104:
* 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'''.  
* find . -uid 1001 -print | xargs -i mv {} /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
* 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 141: Zeile 110:
* 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.  
* xargs -a downloadlist -n 1 -P 4 wget  
xargs -a downloadlist -n 1 -P 4 wget  
* Dieser Befehl übergibt jeweils eine URL aus der Datei '''downloadlist''' an wget.  
* Dieser Befehl übergibt jeweils eine URL aus der Datei '''downloadlist''' an wget.  
* Dabei wird wget vier mal jeweils mit einer anderen Datei gestartet.  
* Dabei wird wget vier mal jeweils mit einer anderen Datei gestartet.  
Zeile 151: Zeile 120:
* The POSIX shell allows us to use:  sh -c '''command-line''' [ ''command-name'' [ ''args''... ] ]
* 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.
* 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 '{}' +
* 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 '{}' +
* 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.


==  Anwendungen ==
===  Beispiel 1 ===
===  Beispiel 1 ===
Wo in meinem Homeordner liegt die Datei "test.pdf"? find ~ -name test.pdf
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.
* 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...  
* find ~ -type f ! -path '*/.*' -mmin -10 -ls
find ~ -type f ! -path '*/.*' -mmin -10 -ls
* Die Optionen im Einzelnen:* ~ -- rekursiv in meinem Homeordner
* Die Optionen im Einzelnen:* ~ -- rekursiv in meinem Homeordner
* -type f -- eine Datei (kein Ordner...)
* -type f -- eine Datei (kein Ordner...)
Zeile 167: Zeile 136:
* Variante: mit Dotfiles, nicht aber Ordner, die mit Punkt beginnen (also ohne .gnome/ oder .kde/ und so weiter, aber mit .bash_history).  
* 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.  
* Und zwar alle Dateien, die nicht älter als zwei Tage sind.  
* find ~ ! -path '*/.*/*' -type f -ctime -2
find ~ ! -path '*/.*/*' -type f -ctime -2
* Im Homeordner alle Dateien finden, deren Namen Leerzeichen enthalten.
* Im Homeordner alle Dateien finden, deren Namen Leerzeichen enthalten.
* Wieder ohne Dateien oder Ordner, die mit Punkt beginnen.  
* 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
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)
* 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.  
* 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 parallell gestartet werden (vgl.  
* Zu beachten: -exec mit''' \+''' abschließen statt mit '''\; '''beschleunigt das Abarbeiten ungemein, weil dann mehrere grep Prozesse parallel gestartet werden (vgl. xargs).  
* xargs).  
* Setzt eine halbwegs aktuelle Version von find voraus.
* Setzt eine halbwegs aktuelle Version von find voraus.
* Hoppla, da sind auch Dateien mit Leerzeichen im Namen dabei? Kein Problem.  
* 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'
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
* finds Option -print0 erzeugt die richtige Ausgabe für xargs Option -0
* 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".  
* 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: 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.  
* Wie vielseitig find ist, zeigt sich schon an der Länge der manpage.  
* Wie vielseitig find ist, zeigt sich schon an der Länge der manpage.  
* Find findet nach Name, Regex, Größe, Datum, Dateityp,...  
* 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 angewendet werden soll.  
* 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.
* Darum wird das Kommando in vielen Shellskripten verwendet.


===  [http://techblog.7d0.de/2009/01/beispiele-zur-benutzung-von-grep-und-find/ Beispiel] 2 ===
===  Beispiel 2 ===
Dateien im aktuellen Ordner und Unterordnern finden, deren Namen einem bestimmen Muster entsprechen: find . -name "*.jpg"
Dateien im aktuellen Ordner und Unterordnern finden, deren Namen einem bestimmen Muster entsprechen:  
* Dateien finden, deren Namen nicht einem bestimmten Muster entsprechen: find . \! -name "*.jpg"
find . -name "*.jpg"
* Dateien finden, deren Namen einem bestimmten Muster entsprechen und die einen bestimmten Text enthalten: find . -name "*.php" -exec grep -il "suchtext" {} \;
* Dateien finden, deren Namen nicht einem bestimmten Muster entsprechen:  
* Dateien finden, die bestimmte Datei-Endungen haben (Mit Regular-Expressions finden): find . -regex ".*(php|html|tpl)$"
find . \! -name "*.jpg"
* Große Dateien finden (Dateien finden, die größer als ca. 500 MB sind): find . -type f -size +500000k -exec ls -lh {} \;
* Dateien finden, deren Namen einem bestimmten Muster entsprechen und die einen bestimmten Text enthalten:  
* Dateien finden, deren Pfade einem bestimmten Pattern entsprechen: find . -path "*/.svn*"
find . -name "*.php" -exec grep -il "suchtext" {} \;
* Dateien finden, deren Pfade nicht einem bestimmten Pattern entsprechen: find . \! -path "*/.svn*"
* Dateien finden, die bestimmte Datei-Endungen haben (Mit Regular-Expressions finden):  
* Dateien finden, die nicht einem bestimmten User (nicht root) gehören: find . \! -user root
find . -regex ".*(php|html|tpl)$"
* Dateien finden, die “oo” oder “ee” im Namen haben: find . \( -name "*oo*" -or -name "*ee*" \)
* Große Dateien finden (Dateien finden, die größer als ca. 500 MB sind):  
* Dateien finden, die nicht “oo” oder “ee” im Namen haben: find . \! \( -name "*oo*" -or -name "*ee*" \)
find . -type f -size +500000k -exec ls -lh {} \;
* Geht nicht mit find (GNU findutils) 4.4.2: '''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)$”
* Dateien finden, deren Pfade einem bestimmten Pattern entsprechen:  
find . -path "*/.svn*"
* Dateien finden, deren Pfade nicht einem bestimmten Pattern entsprechen:  
find . \! -path "*/.svn*"
* Dateien finden, die nicht einem bestimmten User (nicht root) gehören:  
find . \! -user root
* Dateien finden, die “oo” oder “ee” im Namen haben:  
find . \( -name "*oo*" -or -name "*ee*" \)
* Dateien finden, die nicht “oo” oder “ee” im Namen haben:  
find . \! \( -name "*oo*" -or -name "*ee*" \)
* Geht nicht mit find (GNU findutils) 4.4.2: '''
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 222: Zeile 202:
* Geben Sie folgendes ein:[http://www.murnauer.de/mandrakeref/command-find.html#FTN.AEN4397 []
* Geben Sie folgendes ein:[http://www.murnauer.de/mandrakeref/command-find.html#FTN.AEN4397 []


[http://www.murnauer.de/mandrakeref/command-find.html#FTN.AEN4397 Denken Sie daran, dass in diesem Beispiel beide Verzeichnisse auf dem selben Dateisystem sein müssen!]] find \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 -exec  ln {} /home/httpd/obsolete \;
* Denken Sie daran, dass in diesem Beispiel beide Verzeichnisse auf dem selben Dateisystem sein müssen!
  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 238: Zeile 219:
* Sie wollen eine Liste aller JPEG-Dateien, die jünger als die Datei ''stamp'' sind.  
* 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''.  
* 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'': find /shared/images -cnewer    \      /shared/images/stamp      \      -a -iregex ".*\.jpe?g"    \      -a -not -regex ".*/old/.*" \        | mail john -s "Neue Images"
* Sie möchten nicht im Verzeichnis ''old'' suchen, Sie möchten diese Liste zugeschickt bekommen und Ihr Benutzername ist ''john'':  
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…?


== Erweiterte Anwendungen ==
= Dokumentation =
The “''‑print''” action lists the names of files separated by a newline.
== Man-Page ==
* But it is common to ''pipe'' the output of ''find'' into ''xargs'', which uses a space to separate file names.
# XARGS(1) General Commands Manual
* This can lead to problems if any found files contain spaces in their names, as the output doesn't use any quoting.
* In such cases, when the output of ''find'' contains a file name such as “''foo bar''” and is piped into another command, that command “sees” two file names, not one file name containing a space.
* Even without using ''xargs'', you could have a problem if the file name contains a newline character, as most utilities expect one file name per line.
* In such cases, you can specify the action “''‑print0''” instead.
* This lists the found files separated not with a newline but with a ''null'' (or “”) character, which is not a legal character in Unix or Linux file names.
* Of course the command that reads the output of ''find'' must be able to handle such a list of file names.
* Many commands commonly used with ''find'' (such as ''tar'' or ''cpio'') have special options to read in file names separated with NULs instead of spaces.
* Instead of having ''find'' list the files, it can run some command for each file found, using the “''‑exec''” action.
* The ''‑exec'' is followed by some shell command line, ended with a semicolon (“'';</nowiki>''”).


(The semicolon must be quoted from the shell, so ''find'' can see it!) Within that command line, the word “''{}''” will expand out to the name of the found file.
== Info-Pages ==
* See below for some examples.
= Links =
* You can use shell-style wildcards in the ''‑name'' search argument:  find . -name foo\*bar
== Intern ==
* This will search from the current directory down for ''foo*bar'' (that is, any filename that begins with ''foo'' and ends with ''bar'').
== Weblinks ==
* Note that wildcards in the name argument must be quoted so the shell doesn't expand them before passing them to ''find''.
* Also, unlike regular shell wildcards, these will match leading periods in filenames. (For example “''find ‑name \*.txt''” would match “''.foo.txt''”.)
* You can search for other criteria beside the name.
* Also you can list multiple search criteria.
* When you have multiple criteria, any found files must match all listed criteria.
* That is, there is an implied Boolean ''AND'' operator between the listed search criteria. ''find'' also allows ''OR'' and ''NOT'' Boolean operators, as well as grouping, to combine search criteria in powerful ways (not shown here.)
* Here's an example using two search criteria:  find / '''-type f -mtime -7''' | xargs tar -rf weekly_incremental.tar  gzip weekly_incremental.tar
* will find any regular files (i.e., not directories or other special files) with the criterion “''‑type f''”, and only those modified seven or fewer days ago (“''‑mtime ‑7''”).
* Note the use of ''xargs'', a handy utility that coverts a stream of input (in this case the output of ''find'') into command line arguments for the supplied command (in this case ''tar'', used to create a backup archive).
* Using the ''tar'' option “''‑c''” is dangerous here; ''xargs'' may invoke ''tar'' several times if there are many files found, and each “''‑c''” will cause ''tar'' to over-write the previous invocation.
* The “''‑r''” option ''appends'' files to an archive.
* Other options such as those that would permit filenames containing spaces would be useful in a “production quality” backup script.
* Another use of ''xargs'' is illustrated below.
* This command will efficiently remove all files named ''core'' from your system (provided you run the command as root of course):  find / -name core | xargs /bin/rm -f find / -name core -exec /bin/rm -f '{}' \; # same thing find / -name core -delete                  # same if using Gnu find</nowiki>
* The last two forms run the ''rm'' command once per file, and are not as efficient as the first form; but they are safer if file names contain spaces or newlines.
* The first form can be made safer if rewritten to use “''‑print0''” instead of (the default) “''‑print''”. “''‑exec''” can be used more efficiently (see [http://content.hccfl.edu/pollock/Unix/FindCmd.htm#exec Using ][http://content.hccfl.edu/pollock/Unix/FindCmd.htm#exec ‑exec][http://content.hccfl.edu/pollock/Unix/FindCmd.htm#exec  Efficiently] below), but doing so means running the command once with many file names passed as arguments, and so has the same safety issues as with ''xargs''.
* One of my favorite of the ''find'' criteria is used to locate files modified less than 10 minutes ago.
* I use this right after using some system administration tool, to learn which files got changed by that tool:  find / -mmin -10
* This search is also useful when I've downloaded some file but can't locate it, only in that case “''‑cmin''” may work better.
* Keep in mind neither of these criteria is standard; “''‑mtime''” and “''‑ctime''” are standard, but use days and not minutes.
* Another common use is to locate all files owned by a given user (“''‑user ''''username''”).
* This is useful when deleting user accounts.
* You can also find files with various permissions set. “''‑perm /''''permissions''” means to find files with '''any''' of the specified ''permissions'' on, “''‑perm -''''permissions''” means to find files with '''all''' of the specified ''permissions'' on, and “''‑perm ''''permissions''” means to find files with '''exactly''' ''permissions''. ''Permissions'' can be specified either symbolically (preferred) or with an octal number.
* The following will locate files that are writable by “others” (including symlinks, which should be writable by all):  find . -perm -o=w
 
(Using ''‑perm'' is more complex than this example shows.
* You should check both the [http://www.opengroup.org/onlinepubs/9699919799/utilities/find.html#tag_20_47_04 POSIX documentation for ][http://www.opengroup.org/onlinepubs/9699919799/utilities/find.html#tag_20_47_04 find] (which explains how the symbolic modes work) and the [http://www.gnu.org/software/findutils/manual/html_mono/find.html#Overview Gnu ][http://www.gnu.org/software/findutils/manual/html_mono/find.html#Overview find][http://www.gnu.org/software/findutils/manual/html_mono/find.html#Overview  man page] (which describes the Gnu extensions).
* When using ''find'' to locate files for backups, it often pays to use the “''‑depth''” option (really a criterion that is always true), which forces the output to be ''depth-first''—that is, files first and then the directories containing them.
* This helps when the directories have restrictive permissions, and restoring the directory first could prevent the files from restoring at all (and would change the time stamp on the directory in any case).
* Normally, ''find'' returns the directory first, before any of the files in that directory.
* This default behavior is useful when using the “''‑prune''” action to prevent ''find'' from examining any files you want to ignore:
* find / -name /dev -prune ...''other criteria'' | xargs tar ...
* Using just “''find / ‑name /dev ‑prune | xargs tar ...''” won't work as most people might expect.
* This says to only find files named “''/dev''”, and then (if a directory) don't descend into it. So you only get the single directory name “''/dev''”! A better plan is to use the following:  find / ! -path /dev\* |xargs ...
* which says find everything except pathnames that start with “''/dev''”. The “''!''” means Boolean ''NOT''.
* When specifying time with ''find'' options such as ''‑mmin'' (minutes) or ''‑mtime'' (24 hour periods, starting from now), you can specify a number “''n''” to mean exactly ''n'', “''‑n''” to mean less than ''n'', and “''+n''” to mean more than ''n''.
* Fractional 24-hour periods are truncated! That means that “''find ‑mtime +1''” says to match files modified '''two or more days ago.'''
* For example:  find . -mtime 0  # find files modified between now and 1 day ago</nowiki>                  # (i.e., within the past 24 hours)</nowiki> find . -mtime -1  # find files modified less than 1 day ago</nowiki>                  # (i.e., within the past 24 hours, as before)</nowiki> find . -mtime 1  # find files modified between 24 and 48 hours ago</nowiki> find . -mtime +1  # find files modified more than 48 hours ago</nowiki> find . -mmin +5 -mmin -10 # find files modified between                          # 6 and 9 minutes ago</nowiki>
 
===  Find und Sort===
find -type f -print0 | xargs -0 stat -c "%y %n" | sort -r | head -20
 
==== Sort by size====
find -type f -exec ls -ltu {} \; | sort -k 5 -n
 
==== Sort by access time====
find -type f -exec ls -ltu {} \; | sort -k 6 -M
 
==== Search recursively by date====
find -printf "%TY-%Tm-%Td %TT %p\n" | tail -20 | sort -n
* Have you ever wanted to view a list of all files or subdirectories within a directory in Linux and order them by when they were last changed or modified? Then you have come to the right place! Here we are going to provide and explain some useful commands that when piped together will give us this result, allowing us to recursively list files and directories by date.
* This is one of my favourite commands to use when trying to build a timeline of events, for instance if a server or website has been compromised and you want to see when files have been modified with malicious content. By seeing other files that were modified around the same time you can get a better idea of what took place and when, allowing you to correlate these events with your logs.
 
=====  The Commands =====
So here are the simple commands piped together, run this within a directory and you will be provided with a list of all files and subdirectories along with the date they were last modified. The most recently changed contents will be at the bottom of the list, so after running it you’ll see the most recent changes with the older changes as you scroll up. If you have a lot of output piping the whole lot into ‘less’ may be a good idea so that you can easily scroll through. find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2-
* Below is an example output from running this full command. '''
# find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2-</nowiki>'''
Wed Aug 26 09:25:04.0000000000 2015 ./images/1.jpg
Tue Sep  1 06:27:43.0000000000 2015 ./1.JPG
Sat Sep 12 12:36:51.0000000000 2015 ./directory/6.jpg
Sat Sep 12 12:43:48.0166880221 2015 ./directory
Mon Oct 12 05:18:21.0000000000 2015 ./images/7.jpg
Sun Oct 18 08:29:46.0000000000 2015 ./8.jpg
Wed Oct 21 10:50:16.0672628610 2015 ./index.html
* As shown we can see the files sorted from oldest date and time modified to newest. Now let’s break down what each part is actually doing for us.
 
======  [http://linux.die.net/man/1/find Find] ======
First off the find command is run which finds us the list of all files and subdirectories recursively within the current working directory, as specified by the “.” after the find command. To confirm your current working directory you can run the “pwd” command. You can change the “.” to a full directory path instead to list all files and subdirectories in there instead if required, this way you don’t have to be in the directory.
* The “-printf” flag is used to print the output in the format specified, in this case this is ‘%T@ %t %p\n’. The %T@ displays the epoch time, that is the amount of seconds since the 1st of January 1970, the %t shows the files last modification time, the %p displays the files name while \n is simply a new line so that each result in our output shows up on a new line which makes it easier to read and work with.
* It is worth noting that you could also replace %t with %c, which will instead use the files last status change time rather than the modification time. This should show things such as permission changes which don’t actually modify the contents file but change the metadata.
* The output of this find command alone looks like this. 1445424616.6726286100 Wed Oct 21 10:50:16.0672628610 2015 ./index.html
* At this stage the output does not display in any sort of chronological order. We can see the output displayed as expected, the files epoch time followed by the last modification date and time, followed by the file name.
 
======  [http://linux.die.net/man/1/sort Sort] ======
Now with this output you may have noticed that there is no order applied, this is taken care of with the sort command. The -k flag specifies a start position which in this case is 1, the first column being the epoch time.
* The output with the sort is shown below, now we have the files in the same order as the output of the full command string shown previously after sorting by column 1, the epoch time. As the epoch time is all numbers, we also use -n to perform a numerical based sort. 1440581104.0000000000 Wed Aug 26 09:25:04.0000000000 2015 ./images/1.jpg 1441088863.0000000000 Tue Sep  1 06:27:43.0000000000 2015 ./1.JPG 1442061411.0000000000 Sat Sep 12 12:36:51.0000000000 2015 ./directory/6.jpg 1442061828.1668802210 Sat Sep 12 12:43:48.0166880221 2015 ./directory 1444627101.0000000000 Mon Oct 12 05:18:21.0000000000 2015 ./images/7.jpg 1445156986.0000000000 Sun Oct 18 08:29:46.0000000000 2015 ./8.jpg 1445424616.6726286100 Wed Oct 21 10:50:16.0672628610 2015 ./index.html
* We can change -n to -nr which will reverse the output, resulting in the oldest modified files showing at the bottom of the output, rather than the newest.
 
======  [http://linux.die.net/man/1/cut Cut] ======
Now that we have our sorted output we use the cut command to tidy up and print out a more specific selection. By specifying a delimiter with -d of ‘ ‘ we find the first white space which comes after the epoch time and cut everything afterwards.
* At this point we now have the complete output which lists all files by date recursively from the specified directory. The epoch time provided an easy way to perform the sort, but we don’t really need to see that in the final output as it isn’t particularly human readable so it’s been removed after the sort.
 
===== Other Options =====
Of course you can always use the much simpler “ls -lrt” within a directory to view all files within the current working directory from oldest to newest, however this does not take into consideration subfolder contents. Even if we use the recursive option and use “ls -lRrt” we only see the files ordered based on the dates within each directory and not a combination of all subdirectories.
* If you aren’t interested in the subdirectories themselves you could also add a “-type f” to the find command which will only list files, as shown below. find . '''-type f''' -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d ' ' -f2-
* This still lists files within subdirectories, it simply no longer also shows the subdirectory names themselves in the output.
* The opposite can also be done, by using “-type d” which will display only directories and no files. find . '''-type d''' -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d ' ' -f2-
 
=====  Summary =====
By combining a few relatively simple bash commands in Linux we have been able to successfully list all files and subdirectories within a specified directory recursively by their modification or change date, in either ascending or descending order. We can also optionally specify to only view files or directories in the output.
* This command is a great way of building a timeline of events as the chronological output allows us to see the order of file modifications, regardless of where the file is actually located.
 
=====  Quelle =====
* https://www.rootusers.com/how-to-search-all-files-by-date-recursively-in-linux/


==== Weitere Lösungen====
find -type f -printf '%T@ %p\0' | sort -zk 1nr | sed -z 's/^[^ ]* //' | tr '\0' '\n' | head -n 10 find -type f -printf '%T@ %p\n' | sort -k1 -n find -type f -print0 | xargs -0 stat -c "%y %n" | sort find -type f -print0 | xargs -0 stat -f "%m %Sm %N" | sort -rn
* If you have not GNU utilities, you could use newlines as separators instead of nulls, but you'll lose support for filenames containing newlines. find -type f -printf '%T@ %p\n' | sort -k 1nr | sed 's/^[^ ]* //'


===  Compare Filetree===
find directory1 -type d -printf "%P\n" | sort > file1 find directory2 -type d -printf "%P\n" | sort | diff – file1


[[Kategorie:Linux:Befehl]]
[[Kategorie:Linux/Befehl]]
{{DEFAULTSORT:xargs}}

Aktuelle Version vom 6. November 2024, 12:45 Uhr


xargs erstellt Befehlszeilen von der Standardeingabe und führt sie aus

Beschreibung

$ type xargs
xargs ist /usr/bin/xargs
  • This manual page documents the GNU version of xargs. xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or new‐lines, and executes the command (default is echo) one or more times with any initial-arguments followed by items read from standard input. Blank lines on the standard input are ignored.
  • The command line for command is built up until it reaches a system-defined limit (unless the -n and -L options are used). The specified command will be invoked as many times as necessary to use up the list of input items. In general, there will be many fewer invocations of command than there were items in the input. This will normally have significant performance benefits. Some commands can usefully be executed in parallel too; see the -P option.
  • Because Unix filenames can contain blanks and newlines, this default behaviour is often problematic; filenames containing blanks and/or newlines are incorrectly processed by xargs. In these situations it is better to use the -0 option, which prevents such problems. When using this option you will need to ensure that the program which produces the input for xargs also uses a null character as a separator. If that program is GNU find for example, the -print0 option does this for you.
  • If any invocation of the command exits with a status of 255, xargs will stop immediately without reading any further input. An error message is issued on stderr when this happens.

Sollen viele Dateien bearbeiten werden wird für jede Datei ein eigene Befehl abgesetzt.

  • Findet find(1) nun 2000 Dateien des Users toelpel, werden (hintereinander) 2000 Prozesse gestartet, die jeweils eine Datei löschen.
  • Das verlangsamt den Vorgang und erzeugt unnötig Last. rm(1) kann mehrere Dateien auf einmal löschen, ein einzelnes rm(1)-Kommando mit 2000 Argumenten wäre sinnvoller.

xargs erwartet als Parameter ein Kommando, welches dann auf Dateien einer Liste angewandt wird, die von der Standardeingabe gelesen werden.

  • Unter Linux/UNIX kann man fast alle Befehle auf einzelne Datei oder auch auf eine ganze Liste von Dateien anwenden.
  • Wenn dies nicht möglich sein sollte oder sich eine Dateiliste nicht mit Wildcards erstellen lässt, kann man das Kommando xargs verwenden.
  • Wenn viele Dateien (manchmal über den Verzeichnisbaum verteilt) gleichartig behandeln werden sollen, ob die Dateien nun gelöscht, der Eigentümer oder die Zugriffsrechte geändert werden soll, ist find(1) eine gute lösung. find / -user toelpel -exec rm \{\} \;

Installation

Syntax

$ xargs [options] [command [initial-arguments]]

xargs wird mit folgender Syntax in einem Terminal aufgerufen.

  • Kommando1 | xargs [Optionen] Kommando2
  • Hierbei wird das "Kommando2" mit den Argumenten aufgerufen, die das "Kommando1" auf die Standardausgabe gibt.

xargs(1) hat die Funktion Kommandozeilen aus Standard-Input zu erstellen und auszuführen. find / -user toelpel -print | xargs rm

find(1) listet alle Dateien des Users toelpel auf und reicht sie über die Pipe an xargs weiter. xargs(1) nimmt die Liste von der Standardeingabe und bastelt daraus und aus dem rm(1), was ihm als Argument übergeben wurde, ein rm(1)-Kommando mit 2000 Argumenten.

  • Ergebnis: 3 Prozesse anstelle von 2001 Prozessen in der ersten Variante, um 2000 Dateien zu löschen.


Parameter

Optionen

-a [Datei] oder --arg-file=[Datei] Liest die Argumente aus einer Datei anstatt von der Standardeingabe
-0 oder --null Argumente werden aufgrund des NULL-Zeichens getrennt anstatt des Leerzeichen.
  • Jedes Zeichen wird wörtlich genommen.
  • Nützlich in Kombination mit der -print0 Option von find.
-d [Trennzeichen] oder --delimiter=[Trennzeichen] Argumente werden aufgrund des Trennzeichens getrennt anstatt des Leerzeichens.
  • Jedes Zeichen wird wörtlich genommen.
  • Das Trennzeichen kann ein einzelnes Zeichen sein, ein escaptes Zeichen, ein oktaler oder ein hexadezimaler Code.
  • Mehrere Zeichen sind nicht erlaubt.
--help Hilfe anzeigen.
-i Standardmäßig wird "{}" als Ersatz-Zeichenkette verwendet, wie bei der Aktion -exec des Befehls find.
  • xargs fügt dann die Dateiliste an der Stelle ein, wo die Ersatz-Zeichenkette steht.
  • Dies kommt zur Anwendung wenn der Befehl die von xargs erzeugte Dateiliste nicht am Ende erwartet.
-p oder --interactive Fragt vor jeder Ausführung, ob fortgefahren werden soll.
-r oder --no-run-if-empty Führt "Kommando2" nicht aus, wenn die Standardeingabe keine Nicht-Leerzeichen enthält.
-n oder --max-args Führt "Kommando2" auf jeweils eine bestimmt Anzahl von übergebenen Argumenten aus.
-P oder --max-procs Führt "Kommando2" mehrfach aus.
  • Mit der Kombination mit -n kann so eine bessere Auslastung des Systems erreicht werden.
-t oder --verbose Gibt mehr Informationen darüber, was gemacht wird.

Anwendungen

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(1): 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 '{}' +
  • 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".
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
  • 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:

find . -name "*.jpg"
  • Dateien finden, deren Namen nicht einem bestimmten Muster entsprechen:
find . \! -name "*.jpg"
  • Dateien finden, deren Namen einem bestimmten Muster entsprechen und die einen bestimmten Text enthalten:
find . -name "*.php" -exec grep -il "suchtext" {} \;
  • Dateien finden, die bestimmte Datei-Endungen haben (Mit Regular-Expressions finden):
find . -regex ".*(php|html|tpl)$"
  • Große Dateien finden (Dateien finden, die größer als ca. 500 MB sind):
find . -type f -size +500000k -exec ls -lh {} \;
  • Dateien finden, deren Pfade einem bestimmten Pattern entsprechen:
find . -path "*/.svn*"
  • Dateien finden, deren Pfade nicht einem bestimmten Pattern entsprechen:
find . \! -path "*/.svn*"
  • Dateien finden, die nicht einem bestimmten User (nicht root) gehören:
find . \! -user root
  • Dateien finden, die “oo” oder “ee” im Namen haben:
find . \( -name "*oo*" -or -name "*ee*" \)
  • Dateien finden, die nicht “oo” oder “ee” im Namen haben:
find . \! \( -name "*oo*" -or -name "*ee*" \)
  • Geht nicht mit find (GNU findutils) 4.4.2:
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!
 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:
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…?

Dokumentation

Man-Page

  1. XARGS(1) General Commands Manual

Info-Pages

Links

Intern

Weblinks