Orgapage.Net







Suchen Ersetzen und überwachen

Find - Suchen nach Dateinamen
Eine wichtige Basis für viele Aktionen ist der Befehl find. Dieses Kommando durchsucht den Verzeichnisbaum nach Dateien und Verzeichnissen, die bestimmte Eigenschaften (aus einer Vielzahl möglicher Kriterien) aufweisen. Standardmäßig listet find die Namen der gefundenen Dateien auf; auf Wunsch wendet das Programm aber auch einen beliebigen Befehl auf alle Fundstücke an.

find / -name "*.conf"
Dies bedeutet: "Suche in der Verzeichnishierarchie von der Wurzel (/) rekursiv abwärts nach Dateien, die auf .conf enden, und liste sie auf". Damit der Wildcard "*" bei find ankommt, muss man ihn mittels Anführungszeichen vor der Interpretation durch die Shell schützen. Die Shell würde sonst gemäß der Bedeutung dieses Regulären Ausdrucks für * alle Möglichkeiten einsetzen und an find übergeben.

Man kann nicht nur nach Namen suchen.
find . -ctime -7
Dies listet zum Beispiel alle Dateien auf, die innerhalb der letzten 7 Tage erstellt wurden (-mtime für geänderte Dateien)

Nun kann man `find´ auch dazu verwenden, mit den gefundenen Dateien etwas anderes zu tun:
find /home -name "*~" -exec rm "{}" \;

Dies bedeutet: "Lösche alle Dateien unterhalb des Verzeichnisses /home, deren Name auf eine Tilde endet". Auf diese Art wird man die Sicherheitskopien los, die manche Editoren von bearbeiteten Dateien anlegen und die sich dann fröhlich auf der Platte verstreuen.

"-exec" weist find an, den Befehl rm auf das Suchergebnis anzuwenden. Die geschweiften Klammern `{}´ sind in find ein Platzhalter für die Datei, die aktuell bearbeitet, in diesem Fall also von rm gelöscht werden soll. Der Befehl wird mit einem durch "\" vor der Shell geschützten ";" abgeschlossen, um find mitzuteilen, wann die Argumentliste dieses Befehls endet.
Wem das rekursive Löschen im Verzeichnisbaum zu radikal ist, kann find anweisen, vor jeder Befehlsausführung um Erlaubnis zu bitten. Das geht mit dem Parameter -ok
find / -name "*~" -ok rm "{}" \;

Über ein anderes Suchkriterium lassen sich mit find leere Dateien löschen:
find / -empty -ok rm "{}" \;

Für komplexe Suchen können Reguläre Ausdrücke verwendet werden.
find / -regex ".*tmp*"

Folgendes kleines Script z.B. ändert alle Großbuchstaben in Dateien in Kleinbuchstaben.
#!/bin/sh
for i in `find . -name "[A-Z]*.HTM"`; do
mv $i `echo $i | tr ´A-Z´ ´a-z´`
echo "Datei $i wurde geaendert!"
done


Erklärung: In der `for i in ...´-Zeile wird zunächst der in Backticks gesetzte find-Befehl ausgeführt; die Variable i erhält nacheinander die daraus resultierenden Dateinamen zugewiesen. Auch bei dem mv-Befehl wertet das Skript zunächst den Ausdruck zwischen den Backticks aus: Der echo-Befehl schreibt den Inhalt der Variablen $i auf die Standardausgabe; das Pipe-Symbol leitet diese Zeichenkette an tr weiter. Dieser Befehl ersetzt zeichenweise alle großgeschriebenen Buchstaben durch kleingeschriebene und gibt den so geänderten Dateinamen aus, der dann als zweites Argument für mv fungiert.


Grep - Suchen in Dateien
Grep sucht in einer Datei Zeile für Zeile nach einer bestimmten Zeichenkette. Besonders mächtig wird das Tool dadurch, dass es reguläre Ausdrücke beherrscht. Eine simple Suche sieht so aus:

grep "Such das!" datei.txt

Grep durchsucht jetzt Zeile für Zeile von datei.txt nach der Zeichenkette "Such das!".
Mit dem Parameter "-i" ignoriert Grep die Groß- und Kleinschreibung. Standardmäßig gibt das Suchprogramm die Zeilen aus, die den Such-String enthalten.
Mit dem Parameter "-l" listet Grep lediglich die Namen der Dateien mit Treffern auf.
"-n" ergänzt die Ausgabe der gefundenen Zeilen um die Zeilennummer.
Mit "-2" gibt Grep jeweils zwei Zeilen vor und nach der Trefferzeile aus.

Beim Einsatz von Grep kann man sich weitere Möglichkeiten von regulären Ausdrücken zu Nutze machen: "^" symbolisiert den Anfang einer Zeile, "$" das Ende.
Daher trifft "^Satz$" also nur auf Zeilen zu, die lediglich das Wort "Satz" enthalten.

Interessant wird es, wenn man Grep mit Find kombiniert.
Die folgende Anweisung sucht alle HTML-Dateien, die gestern ("-ctime 1") editiert wurden und die eine Mail-Adresse mit .de-Endung enthalten. Angezeigt werden die entsprechenden Zeilen inklusive Zeilennummer:
find /usr/local/httpd/htdocs/ -name "*html" -ctime 1 -print | grep -i -n ´mailto:.*\.de´


Cut, Sort, Uniq (An bestimmtem Zeichen trennen, Ausgabe sortiren und Doppelte Einträge der Ausgabe entfernen)
Man kann jetzt die Ausgabe noch etwas verschönern, indem man sich mit dem Befehl cut gezielt bestimmte Spalten ausgeben lässt, die durch ein bestimmtes Zeichen (hier ein "-Zeichen) getrennt sind: find /usr/local/httpd/htdocs/ -name "*html" -ctime 1 -print | grep -i -n ´mailto:.*\.de´ | cut -d´"´ -f2 | sort | uniq

Dies zeigt lediglich den Teil der Zeile zwischen dem ersten und zweiten Anführungszeichen- Man erhält daher eine Liste mit den "mailto:irgendwer@irgendwo.de". Sort sortiert diese Liste dann noch nach dem Alphabet, und Uniq entfernt alle doppelten Zeilen - jede Mail-Adresse taucht nur noch einmal auf.

Folgendes gibt alle Benutzer aus, die 4-5 stellige UIDs haben.
cat /etc/passwd | grep -E "[0-9]{4,5}" | cut -d: -f1
-d gibt das Trennzeichen an
-f die Spalte, die ausgegeben werden soll

Sed - Textausschnitte ersetzen
Mit Seds regulären Ausdrücken lässt sich sehr präzise formulieren, was man wie ändern möchte. Ein einfaches sed-Beispiel sieht so aus:
sed -e s/Hund/Katze/g datei.txt > datei.neu

Das Bedeutet so viel, wie: "Ersetze alle Vorkommen von Hund durch Katze." Die geänderten Zeilen schreibt sed auf die Standardausgabe, von wo man sie mit einer Output-Umleitung (>) in eine neue Datei schreiben kann.


Awk - Textausschnitte ersetzen Wie Sed bearbeitet auch Awk die einzelnen Zeilen einer Datei. Dieses Tool ist jedoch auf den Umgang mit spaltenweise organisierten Informationen spezialisiert. Angenommen, man will die Gesamtgröße einer partitionierten Festplatte bestimmen. Df zeigt die Belegung der Partitionen:

Anstatt jetzt selbst die Zahlen der 1-KByte-Blöcke in der zweiten Spalte zu addieren, überlässt man Awk diese Arbeit:
df | awk ´/dev/ {summe += $2} END { print summe}´

Im Beispiel nimmt Awk die Zeilen der Df-Ausgabe, die den String "/dev/" enthalten, und addiert die Werte der zweiten Spalte in "summe" auf. Den mit "END" gekennzeichneten Anweisungsblock führt Awk erst aus, wenn das Ende der Eingaben erreicht ist. Im Beispiel wird dann die Summe der Partitionsgrößen ausgegeben. Will man nur den freien Plattenplatz erfahren, addiert man Spalte 4, indem man das "$2" durch "$4" ersetzt.


Tail -f - Änderungen in einer Datei loggen
Tail -f zeigt, was in eine Datei geschrieben wird. Mit
tail -f /var/log/messages
beispielsweise lassen sich die Ausgaben in die LogDatei "online" verfolgen - etwa beim Laden eines Moduls oder beim Aufbau einer PPP-Verbindung.


Watch - wiederholt ausführen
Watch führt ein Programm periodisch immer wieder aus:
watch -n 5 ps ax
beispielsweise zeigt alle fünf Sekunden die aktuell laufenden Prozesse.



Weitere Seiten zu diesem Thema:
URL: Von:
Titel:  
Captcha:
Text bewerten:
Aktuelle Wertung: 0 (0x)
Seit der letzten Änderung: 0 (0x)

Kommentare     Seite: [0]
24. Jun. 2007 - 10:59 erstellt von Martin
Schöne Tuts hier, danke!

aber mal doofe Ergänzungsfrage:
wie kann ich auf der Konsole in dutzenden, über mehrere Unterverzeichnisse versteuten, Seiten einen Textabschnitt ändern? (z.B. in 243 HTML-Seiten mal kurz das Copyright aktualisieren)??? Ciao!
16. Aug. 2007 - 16:02 erstellt von Oliver Peschka
Hi Martin,

ich würde eine Kombination aus
for, find und sed nutzen

Sowas wie:
for DATEIEN in `find . -name "*.html"`
do
sed -e s/Hund/Katze/g $DATEIEN >$DATEIEN.NEU
done


Viel Spass damit.
Grüße,
0li
18. Oct. 2007 - 15:49 erstellt von Jörg
find /usr/local/httpd/htdocs/ -name "*html" -ctime 1 -print | grep -i -n ´mailto:.*\.de´ und die darauf aufbauenden funktionieren nicht. Das müßte wohl
grep -i -n "mailto:.*\.de" `find /usr/local/httpd/htdocs/ -name "*html" -ctime 1 -print` heißen
Von: E-Mail:

Captcha: