Hallo Thomas, hallo Leute, Am Donnerstag, 14. August 2003 14:40 schrieb Thomas Moritz:
Am Donnerstag, 14. August 2003 00:22 schrieb Christian Boltz: zu gern wuerde ich so fit in Sachen Shell sein, wie Du, Jan uva. :-)
Ich habe für diese und meine gestrige Mail auch erst in man bash stöbern müssen ;-) Meist geht es nach dem Motto "Hmmm, IIRC kann das die Bash doch auch, oder? Mal nachsehen..."
BTW: Du verwendest Backticks, um die Variable "$zaehler"eins hochzuzählen: zaehler=`expr $zaehler + 1` Das startet ein externes Programm in einer Subshell - wenig performant ;-) Genausogut funktioniert die (vermutlich bash-spezifische) Variante zaehler=$(($zaehler+1)) - und das ohne Subshell ;-) Eine weitere Variante ohne Subshell wäre let zaehler=$zaehler+1
Deine beiden Beispiele sind laut man bash voellig identisch.
Jepp.
Leider bin ich nicht selbst drauf gestossen:-(
man bash ist ja auch nicht gerade sonderlich übersichtlich ;-)
((expression)) The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION. If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to let "expression".
Genau das. zaehler=$[$zaehler+1] funktioniert übrigens auch ;-)
Wie koennte ich nun auch folgendes besser Loesen?: (vielleicht geht´s ja auch ohne nach cut zu pipen?)
read line myvar=`echo "$line" | cut -c 4-11`
Wenn ich auch hier die SubShell umgehen koennte, wuerde das einen enormen Geschwindigkeitsvorteil bringen - vermute ich mal. Diese Art Variablenzuweisung laeuft mehrfach in einem umfangreichen case - esac Block. Ich war schon auf der Suche nach sowas wie
SrtLen,
${#varable}
StrPos,
Gibt es AFAIK nicht (oder ich hab was übersehen), aber es gibt einige andere nette Tricks ;-) cb@tux:~> TEST=1234567890 cb@tux:~> echo ${TEST#*4} 567890 # alles einschließlich der "4" vorne wegschnippeln cb@tux:~> echo ${TEST%5*} 1234 # alles einschließlich der "5" hinten wegschnippeln Es gibt jeweils auch eine Variante mit doppeltem ## bzw. %%. Der Unterschied liegt darin, ob das erste oder letzte Auftreten des Suchmusters berücksichtigt wird. Da das aber bei meinem $TEST sowieso nicht relevant ist, darfst Du das aber selbst in der manpage nachschlagen ;-) cb@tux:~> echo ${TEST/3/_} 12_4567890 Diese Variante arbeitet mit RegEx, so ist z. B. das folgende möglich: cb@tux:~> echo ${TEST/[a58b]/_} 1234_6789 Aber Achtung: Es wird immer nur das erste Vorkommen ersetzt!
StrMove
Sollte sich durch Zurechtschneiden und erneutes Zusammensetzen einer Variable (ggf. über den Umweg mit Hilfsvariablen) emulieren lassen. Allgemeiner Tip: Abschnitt "Parameter Expansion" in man bash ;-) Vielleicht interessiert Dich auch ein (etwas älteres) Script von mir, das einige solcher ${irgendwelchetricks} verwendet. http://tux.boltz.de.vu (Baugrube, nicht erschrecken ;-) -> diffdirs Aber Vorsicht bei der Verwendung dieses Scripts: ich verwende es hauptsächlich zum Ermitteln nötiger Uploads für Webseiten, also nur bei "braven" Dateinamen. Schon ein Leerzeichen im Dateinamen führt vermutlich zu einem Fehler! Für Webseiten ist diese Einschränkung IMHO sogar vorteilhaft (besser in diesem Stadium ein Fehler als im ErrorLog des Webservers ;-) , aber für andere Dateien ist es eben nachteilig. Auch sonst ist das Script wohl nicht ganz fehlerfrei, aber es erfüllt seinen Zweck ;-) Jedenfalls lade ich nachher noch die aktuelle Version hoch, damit wenigstens die längst behobenen Fehler draußen sind ;-) Apropos@all: die folgende Zeile wirbelt in vim das Syntax-Highlighting durcheinander: SUBDIR="${3:${#VERZALT}+1}"; Ist das ein Bug im vim Syntax-Script oder ist diese Zeile nicht einwandfrei? cb@tux:~/bin> vim --version | head -n1 VIM - Vi IMproved 6.1 (2002 Mar 24, compiled Aug 5 2003 13:26:57)
usw. In dieser Art scheint es jedoch kein Aequivalent in der Shell zu geben - sagt jedenfalls 'bash -c help' und in 'man bash' wurde ich auch nicht fuendig. Vielleicht habe ich ja wieder Tomaten auf den Augen?
Könnte sein - ich musste allerdings auch erstmal in man bash nachschlagen: ${parameter:offset} ${parameter:offset:length} Substring Expansion. Expands to up to length char- acters of parameter starting at the character spec- ified by offset. If length is omitted, expands to the substring of parameter starting at the charac- ter specified by offset. length and offset are arithmetic expressions (see ARITHMETIC EVALUATION below). length must evaluate to a number greater than or equal to zero. If offset evaluates to a number less than zero, the value is used as an off- set from the end of the value of parameter. If parameter is @, the result is length positional parameters beginning at offset. If parameter is an array name indexed by @ or *, the result is the length members of the array beginning with ${param- eter[offset]}. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1. Somit auf Deinen Bedarf übertragen:
read line myvar=`echo "$line" | cut -c 4-11`
cb@tux:~> TEST=1234567890abcdefghijklmnopqrstuvwxyz cb@tux:~> echo $TEST | cut -c 4-11 # zum Vergleich 4567890a cb@tux:~> echo ${TEST:3:8} 4567890a Die gesuchte Befehlszeile ist also myvar=${line:3:8} Dann mal viel Spaß beim Beschleunigen des Scripts! Sonst noch irgendwelche Subshells? ;-) Gruß Christian Boltz PS: Ich schätze mal, dass ${var:offset:length} und sonstige Spezialitäten mal wieder bash- oder POSIX-spezifisch sind, also nicht mit (jeder) /bin/sh läuft ;-) -- [Virenscanner] Stattdessen gehört auf einen Windows-Arbeitsplatz ein guter, selbstaktualisierender lokaler Scanner, der die Windows-Kiste so richtig schön langsam beim Öffnen von Dateien macht, um den Windows-Anwender zu motivieren, auf Linux umzusteigen. [Kristian Koehntopp in suse-linux]