Dateien und Ordner Rekursiv per FTP mittels Shell Script hochladen

Eine Bemerkung zum Beginn: Rein aus Sicherheitsgründen verwende ich FTP nicht gern. Aber bei einigen Projekten kommt man nicht herum sich damit auseinanderzusetzen, da der Hoster dies als einzige Datenübertragungsmethode anbietet.

Nun aber zum Problem. Der Standard FTP Client „ftp“ kann mehrere Dateien mit mput verarbeiten. Leider ist diese Funktion nicht rekursiv. Gerade beim Upload von mehreren Dateien und Ordnern via Script wird es schnell aufwändig. Einen ganz charmanten Ansatz bietet ncftp. Dort kann ich mput mit dem Paramater -R verwenden und Rekursiv hochladen.

Wenn das Paket noch nicht auf der Maschine installiert ist, kann das mit folgendem Befehl nachgeholt werden.

sudo apt-get install ncftp

Nun das Script zum Upload:

#!/bin/bash
HOST='ftp.domain.de'
USER='ftpusername'
PASSWD='ftppassword'

ncftp -u $USER -p $PASSWD $HOST << EOT
passive
ascii
cd /remote_directory
lcd /local/upload/directory/
mput -R *
bye
EOT

Weitere Informationen zum Thema:
http://www.ncftp.com/

pcregrep gegen grep

Um mit reguläre Ausdrücken auf der Linux-Konsole zu suchen, verwendete ich meist das Programm grep. Zufällig bin ich jetzt auf pcregrep gestoßen. Das kleine Tool befindet sich in den Paketquellen von Ubuntu und kann wie folgt installiert werden.

$ sudo apt-get install pcregrep

Im direkten Vergleich zeigt sich, das pcregrep deutlich schneller bei der Verarbeitung von Perl Kompatiblen Ausdrücken ist als grep -E.

$ time grep -o -E ‚^[0-9.]+\s‘ access.log > /dev/null
real 0m1.526s
user 0m1.508s
sys 0m0.012s

im Vergleich zu ….

$ time pcregrep -o ‚^[0-9.]+(?=\s)‘ access.log > /dev/null
real 0m0.036s
user 0m0.032s
sys 0m0.000s

Die Grundlage des Vergleichs ist die Suche nach IP Adressen in einer ca. 7 MB großen access.log Datei eines Apache. Wenn man das Ergebnis mal hochrechnet auf eine GB große Datei, macht sich der Unterschied schon ganz schön bemerkbar.

Weitere Informationen zum Thema:
http://manpages.ubuntu.com/manpages/precise/man1/pcregrep.1.html
http://manpages.ubuntu.com/manpages/precise/man1/grep.1.html

Inhalt mehrerer Dateien in einer Datei Zusammenführen

Heute mal ein kleiner Schnipsel der sicherlich für den ein oder anderen hilfreich sein kann. Es geht um das Zusammenführen des Inhalts von zwei oder mehr Dateien. Hierfür kann z.B. der Befehl cat verwendet werden.

$ cat datei1.txt datei2.txt > datei12.txt

Selbstverständlich lässt sich der Befehl auch prima mit einem find oder ls kombinieren. Damit lassen sich dann auch ganze Order oder nur bestimmte Dateien in einem Verzeichnis zusammenführen.

Doppelte Zeilen aus Datei entfernen

Heute habe ich eine Excel Tabelle erhalten, die ich in eine Datenbanktabelle importieren wollte. Das Problem: die Quelle hatte einige Dopplungen die mit dem UNIQUE KEY der Datenbanktabelle kollidierten. Damit der Import der weit über 16000 Zeilen ohne händisches Zutun importiert werden konnte, musste ein Script her.

Die Lösung ist eine Kombination der Programme cat, sort und uniq. Diese erledigt die Arbeit sogar in einer Zeile.

Die folgende Zeile entfernt doppelte Einträge und speichert das Ergebnis dann in einer neuen Datei ab.

$ cat dateiname | sort | uniq > dateiname.neu

Weitere Informationen zum Thema:
http://manpages.ubuntu.com/manpages/lucid/en/man1/cat.1.html
http://manpages.ubuntu.com/manpages/lucid/en/man1/sort.1.html
http://manpages.ubuntu.com/manpages/lucid/en/man1/uniq.1.html

Bash Historie mit Zeitstempel versehen

Die Historie der Bash finde ich persönlich recht nützlich. Gerade um die letzten Befehle mittels Pfeil-Auf und Pfeil-Ab Tasten noch einmal auszuführen. Doch die Historie kann noch mehr! Die Gesamte Historie kann man sich mit dem folgenden Befehl anzeigen lassen. (Hinweis: Ich übergebe die Historie an less da meist der Anzeigepuffer des Terminals nicht ausreicht, um alle Befehle anzuzeigen.)

$ history | less

Ein Nachteil der Standard Einstellung ist, das alle Befehle nur der Reihe nach aufgelistet werden. Der Historie kann aber auch ein Zeitstempel zugewiesen werden, z.B. um das Durchsuchen der Historie nach einem bestimmten Tag oder Zeitraum zu ermöglichen.

Dies kann entweder dynamisch erfolgen …

$ export HISTTIMEFORMAT=“[%F] [%T] „

… oder besser noch, direkt in die Konfiguration der Bash geschrieben werden. In der Datei ~/.bashrc muss dazu die folgende Zeile ergänzt werden:

HISTTIMEFORMAT="[%F] [%T] "

Bei der Zweiten Variante ist zu beachten, das die Bash/Sitzung neu gestartet werden muss.

Weitere Informationen zum Thema:
http://manpages.ubuntu.com/manpages/hardy/man3/history.3readline.html