Mittwoch, 28. Januar 2009
Zahlenkolonnen formatieren mit (g)awk
13.5 556.987 14.56 13.1 15.356 345.2 416.106 2.7 17.1 3.99 18.41 4.342 139.14 345.2 20.21 20.1 621.18 4.5 22.01 77.2 23.1 94.627Das sieht nicht so toll aus... Mit Müh und Not kann man zwei Spalten mit Fließkommazahlen erkennen, jeweils durch ein Leerzeichen getrennt. Gawk wirds richten:
"Zahlenkolonnen formatieren mit (g)awk" vollständig lesen
Samstag, 17. Januar 2009
Tipps und Beispiele für "find"
Ein einfaches Beispiel:
Wo in meinem Homeordner liegt die Datei "test.pdf"?
Irgendwo in eurem Homeordner, irgendein Name, vor ein paar Minuten...
~ -- 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)
Das war noch lange nicht alles...
"Tipps und Beispiele für "find"" vollständig lesen
Dienstag, 6. Januar 2009
URL decode und encode in der Bash
Beispiel zum Encodieren:
Beispiel zum Decodieren:
Das funktioniert, ist aber nicht besonders komfortabel. Wir wissen uns aber zu helfen:
"URL decode und encode in der Bash" vollständig lesen
Sonntag, 28. Dezember 2008
Rechnen in der Shell
- bash builtin
- bc
- (g)awk
Einfache Rechenoperationen mit Ganzzahlen kann die Bash auch selbst ausführen.
Negative Zahlen und Variablen sind auch kein Problem.
Für einfache Berechnungen ist das ausreichend, wenn es genauer sein soll, ist eine andere Methode erforderlich.
"Rechnen in der Shell" vollständig lesen
Freitag, 26. Dezember 2008
Sed ersetzt das Kommazeichen
Eine Beispielzeile des Textes:
389 0.79% 1.25 Mb 0.21% /gimp1.2/zuschneiden.htmlDas passende sed-Kommando lautet so:
Die Basis für das Ganze ist sed's "substitute", also s (=ersetzen).
Bei meinem Problem geht es nur um Punkte, die von Zahlen eingeschlossen sind. Vorne sind es nie mehr als drei Stellen, es ist aber mindestens eine.
Nun will ich aber nur den Punkt ersetzen, die Zahlen aber selbstverständlich mitnehmen. Sed kennt dazu Platzhalter (\1, \2 usw.), die sich auf einen Ausdruck in Runden Klammern beziehen.
Die Regex (Regular Expresssion)
In der csv-Datei haben alle Zahlen zwei Nachkommastellen. Die passende Regex schaut so aus:
s/ \([0-9]\{1,3\}\) \. \([0-9]\{2\}\) % / \1,\2 /g Punkt Prozent Regex 1 Regex 2 Referenz 1 Referenz 2 BeistrichZusammenfassung:
Regex 1 = 1 bis 3-stellige Zahl
\. = ein (wörtlicher) Punkt
Regex 2 = 2-stellige Zahl (Nachkommastellen)
% = ein Prozentzeichen (wird wegfallen)
\1 = Referenz auf die erste Regex
, = der Beistrich (ersetzt den Punkt)
\2 = Referenz auf die zweite Regex
Sinnvollerweise wird das sed-Kommando in einer Pipe verwendet, z.B.
Das Ergebnis (vgl. Beispielzeile oben):
389 0,79 1.25 Mb 0,21 /gimp1.2/zuschneiden.html
Samstag, 22. November 2008
Der letzte Tag eines Monats
Folgendes Skript (ultimo.sh) ist zum Testen gedacht. Es erwartet genau zwei Parameter: den Monat (zweistellig) und das Jahr (vierstellig).
#!/bin/bash month=$1 year=$2 function ultimo () { lastsec=$(echo $(( `date -d ${year}${month}01 +%s` -1)) ) lastday=$(echo $lastsec | gawk '{print strftime("%d",$1)}' ) echo $lastday ist der letzte Tag des Vormonats von $month im Jahr $year } ultimo exit 0Aufgerufen wird es so:
Ergebnis: 28 ist der letzte Tag des Vormonats von 03 im Jahr 2002
Was so viel bedeutet wie "der Februar 2002 hatte 28 Tage"
Die Idee dahinter ist einfach: Ich nehme den ersten Tag des Folgemonats, Sekunde 0, und ziehe davon eine Sekunde ab.
Konkretere Beispiele:
• Wenn ich aus irgendeinem umfangreichen Logfile den genauen Monat automatisiert extrahieren möchte, brauche ich den ersten und letzten Tag des Monats.
• SARG (Squid Analysis Report Generator) erwartet zum Auswerten eines Monats die Option
"-d 01/MM/YYYY-letzterTag/MM/YYYY"
Update: Micha Holzmann ist über diesen Beitrag gestolpert und hat das Ganze an seine Anforderungen angepasst.
Achtung, hier wird der letzte Tag des abgefragten Monats ausgegeben, nicht der des Vormonats wie oben.
#!/bin/bash month=$1 year=$2 function ultimo () { lastday=$(date -d "${year}-${month}-01 +1 month -1 day" +%d) echo $lastday ist der letzte Tag des Monats ${month}/${year} } ultimo exit 0
Hier wird auf gawk ganz verzichtet, somit ist date das einzige externe Programm, das benötigt wird.
Mittwoch, 19. November 2008
Vor wie vielen Tagen war ein Datum
"date" kann nicht nur das heutige, sondern auch ein Datum in der Vergangenheit in anderer Form darstellen.
Bei der Eingabe ginge zwar auch z.B. JJMMTT, aber um Mißverständnissen vorzubeugen, besser JJJJMMTT verwenden. Welches Datum wäre z.B. 070706? Der 7. Juli 2006 oder der 6. Juli 2007?
date rechnet das Datum in den Unixtimestamp (=Sekunden seit 1.1.1970 00:00:00) um, mit dem ich dann rechnen kann.
Vorsicht, hier verwende ich der Übersicht halber ausnahmsweise Backtick Operators, die zum Copy-Pasten oft ein Horror sind.
Das Ganze funktioniert natürlich auch mit Datum vor 1970:
Das könnte man natürlich noch in Jahre umrechnen:
Meist geht es mir aber nicht um so weit in der Vergangenheit Liegendes.
Ich brauche z.B. die Anzahl der Tage für find, um in einem (Log-)Archiv alle Dateien zu löschen, die vor einem Stichtag angelegt wurden.
Ein Beispiel mit Stichtag 1.1.2008 (diesmal sekundengenau):
323
find . -daystart -maxdepth 1 -type f -ctime +323 -ls