Mittwoch, 16. Februar 2011

Strings in Dateien finden u. mit vim nacheinander abarbeiten

Mal angenommen es existieren diverse Dateien in einem Ordner.
In Manchen Dateien taucht der string 'user=xxx' auf.
Nun moechte ich alle Dateien in denen 'user=' auftaucht nach einander editieren ohne jede datei einzeln öffnen zu müssen.

for i in $(grep -l 'user=' `find files/`) ;do vim +/user= $i ;done


grep -l 'user='
-> listet lediglich /Pfad/Dateiname aller Dateien welche den String 'user=' enthalten

vim +/user=
-> Vim springt in die erste Zeile welche 'user=' enthaelt


Alle Dateien werden der reihe nach geöffnet bis keine mehr übrig ist.

Getestet: bash, zsh

Donnerstag, 10. Februar 2011

Bash Skripten Optionen übergeben

Es gibt viele Möglichkeiten einem Shellskript Optionen mit oder
ohne Argumente zu übergeben.
In diesem Howto werden einige Techniken vorgestellt.

1.0 Einleitung
Ein typischer Aufruf eines Bash Skriptes mit Argumenten:

$ sh script.sh arg1 arg2


|_________|____|____ $0
|____|____ $1
|____ $2 ...
Wie man sieht wurden die Positionsparameter arg1 und arg2
den Variablen $1 und $2 übergeben, während der
Programmname in $0 gespeichert ist.

Folgendes Skript soll dies veranschaulichen:

$ cat args.sh


#!/bin/bash
echo "Program = [ $0 ]"
echo "arg 1 = [ $1 ]"
echo "Alles = [ $* ]"


$ sh args.sh foo bar


1.1 Einfache Optionen ohne Argumente
Eine Option besteht in diesem Fall aus einer
einzelnen Zeichenkette (String).
Die gesuchten Strings sollen sein 'foo' und 'bar'

$ cat option01.sh


#!/bin/bash
for i in $* ;do
case $i in
foo ) echo "foo" ;;
bar ) echo "bar" ;;
esac
done


$ sh option01.sh foo bar

Bei diesem Programm werden jeweils die dem Skript
mitgegeben Optionen mittels dem Befehl 'echo' auf stdout
ausgegeben sofern sie 'foo' oder 'bar' entsprechen.
Dazu werden alle Argumente der Variable '$*' einer 'for'
Schleife übergeben und mittels 'case' Anweisung
auf 'foo' oder 'bar' untersucht.


1.2 Einfache Optionen mit Argumenten
In diesem Besipielskript soll einer Option ein Argument
übergeben werden können. Die Syntax des zu übergebenden
Argumentes setzt sich wie folgt zusammen: option=argument

$ cat option02.sh


#!/bin/bash
for i in $* ;do
case $i in
-foo=* ) ARG_FOO="${i:5:10}" ;;
esac
done
if [ "$ARG_FOO" = "size" ] ;then ls -sh $0
elif [ "$ARG_FOO" = "perm" ] ;then ls -la $0 ;fi


$ sh option02.sh -foo=size
$ sh option02.sh -foo=perm

Mittels 'case' Anweisung wird nach Ausdruecken gefiltert
welche mit '-foo=' beginnen.
"${i:5:10}" beschraenkt die Ausgabe der Variable
$i auf das 6. bis 11. Zeichen.
Es können auch andere Zeichenstromeditoren
wie awk, sed oder grep verwendet werden um Optionen u.
Argument von einander zu separieren.
Besser geeignet ist allerdings die nächste vorgestellte Methode.


1.3 Optionen mit oder ohne Argumente
Bei vielen Optionen welche mit oder ohne Argumente
verarbeitet werden muessen kann es ziehmlich schnell
passieren das der Programmcode sehr unleserlich wird.
Um an dieser Stelle abhilfe zu schaffen gibt es in der
Bash den Befehl 'getopts' mit hilfe dessen Optionen und
Argumente wie bei UNIX ueblichen Befehlen übergeben
und verarbeitet werden können.

Das Skript Soll folgende Aufgaben erfuellen:
- Anzahl der Argumente ermitteln [-c]
- Option welche entweder die PID oder den Porgrammnamen
ausgibt [-p pid ; -p name ]

$ cat option03.sh


#!/bin/bash
_options ()
{
while getopts ":cp:" opt; do :
case $opt in
c ) COUNT=1 ;;
p ) PROG=$OPTARG ;;
\? ) echo "count [-c], Pid & Name [-p]<name, pid>"
esac
done
}
shift $((OPTIND -1))
if [ -z "$1" ] ;then echo "kein argument :-("
else _options $* ;fi
if [ "$COUNT" = 1 ] ;then echo "args = [ $# ]" ;fi
if [ "$PROG" = "pid" ] ;then echo "pid = [ $$ ]" ;fi
if [ "$PROG" = "name" ] ;then echo "name = [ $0 ]" ;fi


$ sh option03.sh -c -p name
$ sh option03.sh -cp pid

Wie oben bereits erwaeht wurde hier der 'getopts'
Befehl verwendet und einer 'while' Schleife
übergeben. Solange getopts ein Argument beinhaltet
ist dessen Return- Wert = 0 andernfalls beendet getopts
mit Return = 1 was wiederum auch die while Schleife
dazu veranlasst zu enden.

Die Optionen welche getopts mitgegeben wurden sind
c p: (getopts ":cp:"). Wird an eine Option ein
Doppelpunkt angehängt wie bei 'p:' wertet getopts
den darauf folgenden Parameter als Argument von 'p'
welches in der variable '$GETOPTS' vorgehalten wird.
-p 42 => Option = 'p' Argument = '42'
Andernfalls wird nur die Option eingelesen ohne das
ihr ein Argument übergeben wird, wie bei 'c'.

mit '[ -z "$1" ]' wird geprüft ob der Inhalt von
'$1 = Nichts' entspricht. Equivalent dazu könnte
dies auch mit: [ $# = 0 ] geprüft werden.
Ist '$1' ungleich nichts wird die Funktion
'_options' mit '$*' Aufgerufen, damit alle Argumente
des Skriptes an 'getopts' weitergereicht werden
koennen.


Glossar
- Positionsparameter = Der reihenfolge nach dem Skript
uebergebene Argumente: $1 $2 ...
- String = Zeichenkette ('123' oder 'abc' ...)

Bash variablen:
$1 - $9 = Positionsparameter 1 - 9. In der Bash koennen
auch mehr als neun Parameter uebergeben werden welche
allerdings nach dem 9. mit geschweiften klammern
aufgerufen werden muessen ${10} ${11} ...
$$ = Prozess ID des Skriptes
$0 = Programmname
$* = Alle dem Skript uebergebenen Parameter.
-z = nichts
-n = ungleich nichts

Linksammlung
Advanced Bash-Scripting Guide
Bash Projektseite
Wikipedia