Hi,
Habe ein kleines problem bei einem Shell Script bei dem ich einfach
nicht weiter komme ich möchte aus einer datei aufgebaut wie
telefonliste.txt die einzelnen Felder getrennt durch ; in jeweils eine
Variable übergeben als einzelnen Command funktiniert der ansatz aber im
Script nicht (dort wir nur eine leerzeile ausgegeben , komme nicht
darauf warum
im Voraus schonmal danke für euer Hilfe
gruß
Fred
echo "1;2;3;4" | read BK VN NN ; echo $BK
#1
Hallo, On Mon, 16 Sep 2002, Fred Kastl wrote:
Habe ein kleines problem bei einem Shell Script bei dem ich einfach nicht weiter komme ich möchte aus einer datei aufgebaut wie telefonliste.txt die einzelnen Felder getrennt durch ; in jeweils eine Variable übergeben als einzelnen Command funktiniert der ansatz aber im Script nicht (dort wir nur eine leerzeile ausgegeben , komme nicht darauf warum [..]
ALLES;;;;;;;BRD;;;0190;3490500;0190;;;;;;;;85;;Scall - Nummer;;Alles;;;; ALLES;;;;;;;BRD;;;0190;3490500;0190;;;;;;;;85;;Scall - Nummer;;Alles;;;; ALLES;;;;;;;BRD;;;0190;3490500;0190;;;;;;;;85;;Scall - Nummer;;Alles;;;;
<END telefonliste.txt>
<fadress>
#!/bin/sh # # fadress #
DBFILE=telefonliste.txt DBCONTENT=$( sed s/" "/"_"/g $DBFILE)
*autsch* Denk die ein File > 1 MB...
search_func() { for i in $DBCONTENT; do IFS=';' echo $i | read BK VN NN ST HN WO PL VWP TP VWG TG VWF TF VWS TS VWH TH B GB NR BS AB EMAIL FIRMA SP STATUS DYNDNS EMAIL echo "$VN" done }
search_func
<END fadress>
==== Vorschlag ==== #!/bin/bash DBFILE="telefonliste.txt" sed 's/ /_/g' < "$DBFILE" | \ ( IFS=";" while read BK VN NN ST HN WO PL VWP TP VWG TG VWF TF VWS TS VWH TH B GB NR BS AB EMAIL FIRMA SP STATUS DYNDNS EMAIL do echo "'$BK' '$VN' '$VWP' '$TG' '$VWF'" done ) ==== Und ja, AFAIK geht's ohne subshell net... -dnh -- Give a man fire, and he will be warm for a day, set a man on fire, and he will be warm for the rest of his life.
On 16 Sep 2002 at 20:21, David Haller wrote:
On Mon, 16 Sep 2002, Fred Kastl wrote:
Habe ein kleines problem bei einem Shell Script bei dem ich einfach nicht weiter komme ich möchte aus einer datei aufgebaut wie telefonliste.txt die einzelnen Felder getrennt durch ; in jeweils eine Variable übergeben als einzelnen Command funktiniert der ansatz aber im Script nicht (dort wir nur eine leerzeile ausgegeben , komme nicht darauf warum [..]
ALLES;;;;;;;BRD;;;0190;3490500;0190;;;;;;;;85;;Scall - Nummer;;Alles;;;; ALLES;;;;;;;BRD;;;0190;3490500;0190;;;;;;;;85;;Scall - Nummer;;Alles;;;; ALLES;;;;;;;BRD;;;0190;3490500;0190;;;;;;;;85;;Scall - Nummer;;Alles;;;;
<END telefonliste.txt>
<fadress>
#!/bin/sh # # fadress #
DBFILE=telefonliste.txt DBCONTENT=$( sed s/" "/"_"/g $DBFILE)
*autsch* Denk die ein File > 1 MB...
oder > 1 GB :-)
search_func() { for i in $DBCONTENT; do IFS=';' echo $i | read BK VN NN ST HN WO PL VWP TP VWG TG VWF TF VWS TS VWH TH B GB NR BS AB EMAIL FIRMA SP STATUS DYNDNS EMAIL echo "$VN" done }
search_func
<END fadress>
==== Vorschlag ==== #!/bin/bash DBFILE="telefonliste.txt"
sed 's/ /_/g' < "$DBFILE" | \ ( IFS=";" while read BK VN NN ST HN WO PL VWP TP VWG TG VWF TF VWS TS VWH TH B GB NR BS AB EMAIL FIRMA SP STATUS DYNDNS EMAIL do echo "'$BK' '$VN' '$VWP' '$TG' '$VWF'" done ) ====
Und ja, AFAIK geht's ohne subshell net...
Vielleicht sollte man hier doch mal über den Einsatz von awk nachdenken? Dann spart man sich auch das Maskieren des Blank und das Jonglieren mit IFS: awk ' BEGIN { FS = ";" } { print $1, $2, $8, ...; } ' telefonliste.txt
Give a man fire, and he will be warm for a day, set a man on fire, and he will be warm for the rest of his life.
*aua* Humor der pechschwarzen Art ;-) Jan P.S. : Sorry für etwaige Ausrutscher meines Mailers, bin mit Pegasus noch nicht richtig warm.
Hallo, On Mon, 16 Sep 2002, Jan Trippler wrote:
On 16 Sep 2002 at 20:21, David Haller wrote:
On Mon, 16 Sep 2002, Fred Kastl wrote: [bitte weiter oben im Thread nachschlagen]
DBFILE=telefonliste.txt DBCONTENT=$( sed s/" "/"_"/g $DBFILE)
*autsch* Denk die ein File > 1 MB...
oder > 1 GB :-)
Ebent *eg* oder > 1 TB... (ok, ein plain-text-db-file > 1 TB, das ist dann nicht mehr nur krank...) [bitte weiter oben im Thread nachschlagen]
==== Vorschlag ==== #!/bin/bash DBFILE="telefonliste.txt"
sed 's/ /_/g' < "$DBFILE" | \ ( IFS=";" while read BK VN NN ST HN WO PL VWP TP VWG TG VWF TF VWS TS VWH TH B GB NR BS AB EMAIL FIRMA SP STATUS DYNDNS EMAIL do echo "'$BK' '$VN' '$VWP' '$TG' '$VWF'" done ) ====
Und ja, AFAIK geht's ohne subshell net...
Vielleicht sollte man hier doch mal über den Einsatz von awk nachdenken? Dann spart man sich auch das Maskieren des Blank und das Jonglieren mit IFS:
awk ' BEGIN { FS = ";" } { print $1, $2, $8, ...; } ' telefonliste.txt
ACK. awk ist _dann_ sehr bald (aber nicht unbedingt sofort) das Mittel der Wahl -- wobei die Grenze zu perl wohl recht fliessend ist: perl -e 'my ($BK, $VN, ...) = split(';', $_); print $BK ...;' Was jew. angebrachter ist haengt dann schnell von Vorkenntnissen und der weiter erwuenschten Verarbeitung der so erlangten Variablen ab ;) Wenn z.B. mit $1, $9, $12 (in awk) noch "einiges" angestellt werden soll, da wuerde ich dann sehr schnell zu perl greifen ;) Achso: ja, ich mag awk, obwohl ich bisher nur Bruchteile davon kenne, ein 'BEGIN{ FS='x'; } /REGEX/{ gsub('bla', 'fasel'); }' (??) hat seine Reize und Vorteile gegenueber perl (und sed) ;) Leider lande ich meist zu schnell vom sed aus beim perl ;)
-- Give a man fire, and he will be warm for a day, set a man on fire, and he will be warm for the rest of his life.
*aua*
Fieso? Stimmt doch!
Humor der pechschwarzen Art ;-)
Ja, was meinst du, warum ich das gesiggt hab? *harharhar* -dnh -- It would have been better for source code control to post our source code to comp.sources.unix and retrieve the versions using groups.google.com than to put it into that bletcherous piece of crap. -- Paul Tomblin on Visual Source Safe
On 17 Sep 2002 at 1:59, David Haller wrote:
On Mon, 16 Sep 2002, Jan Trippler wrote:
On 16 Sep 2002 at 20:21, David Haller wrote:
On Mon, 16 Sep 2002, Fred Kastl wrote: [...] [bitte weiter oben im Thread nachschlagen] ==== Vorschlag ==== #!/bin/bash DBFILE="telefonliste.txt"
sed 's/ /_/g' < "$DBFILE" | \ ( IFS=";" while read BK VN NN ST HN WO PL VWP TP VWG TG VWF TF VWS TS VWH TH B GB NR BS AB EMAIL FIRMA SP STATUS DYNDNS EMAIL do echo "'$BK' '$VN' '$VWP' '$TG' '$VWF'" done ) ====
Und ja, AFAIK geht's ohne subshell net... [awk und perl]
Mir ist übrigens noch ne Variante eingefallen, die ist zwar nicht unbedingt eleganter, vermeidet aber auch das Maskieren der Blanks und die Vergewohltätigung von IFS: #!/bin/bash DBFILE="telefonliste.txt" cat $DBFILE | while read zeile; do BK="`echo $zeile | cut -f1 -d:`" VN="`echo $zeile | cut -f2 -d:`" # usw. done Jan
Hallo, On Tue, 17 Sep 2002, Jan Trippler wrote:
On 17 Sep 2002 at 1:59, David Haller wrote:
On Mon, 16 Sep 2002, Jan Trippler wrote:
On 16 Sep 2002 at 20:21, David Haller wrote:
On Mon, 16 Sep 2002, Fred Kastl wrote: [...] [bitte weiter oben im Thread nachschlagen] ==== Vorschlag ==== #!/bin/bash DBFILE="telefonliste.txt"
sed 's/ /_/g' < "$DBFILE" | \ ( IFS=";" while read BK VN NN ST HN WO PL VWP TP VWG TG VWF TF VWS TS VWH TH B GB NR BS AB EMAIL FIRMA SP STATUS DYNDNS EMAIL do echo "'$BK' '$VN' '$VWP' '$TG' '$VWF'" done ) ====
Und ja, AFAIK geht's ohne subshell net... [awk und perl]
Mir ist übrigens noch ne Variante eingefallen, die ist zwar nicht unbedingt eleganter, vermeidet aber auch das Maskieren der Blanks und die Vergewohltätigung von IFS:
#!/bin/bash DBFILE="telefonliste.txt"
cat $DBFILE | while read zeile; do BK="`echo $zeile | cut -f1 -d:`" VN="`echo $zeile | cut -f2 -d:`" # usw. done
*boerks* (du meintest uebrigens '-d;', nicht '-d:'... Uebrigens: ich habe die Erfahrung gemacht, dass obige Quotingweise falsch ist, wenn z.B. Leerzeichen auftauchen, richtig ist: BK=`echo "$zeile" | ...` Die "geechote" Variable muss gequotet werden, die `` nicht. Dann eher noch: ==== sed 's/ /_/g' < $DBFILE | \ while read zeile do OIFS="$IFS"; IFS=";" set -- $zeile ## nein, $zeile darf hier nicht gequotet werden! IFS="$OIFS" BK="$1"; VN="$2"; NN="$3"; ST="$4"; HN="$5"; WO="$6" PL="$7" VWP="$8"; TP="$9"; VWG="${10}"; TG="${11}"; VWF="${12}" # ... done ==== Zur Erinnerung: einen externen Prozess aufzurufen ist "teuer". Und das pro Zeile einmal pro Variable duerfte dir die Performance recht deutlich versauen. -d'*scnr*'nh -- Ihr Scherzkekse! Computer - und das sollte bekannt sein - rechnen garnicht. Sie setzten oder löschen bits. Nicht mehr, nicht weniger. Daß dies gelegentlich wie "Rechnen" oder "Usenet" oder "Display Postscript" aussieht ist eher Zufall, trägt aber zur Erhaltung der Art bei. -- Dietz Proepper in dasr
On 18 Sep 2002 at 5:43, David Haller wrote:
On Tue, 17 Sep 2002, Jan Trippler wrote: [...]
#!/bin/bash DBFILE="telefonliste.txt"
cat $DBFILE | while read zeile; do BK="`echo $zeile | cut -f1 -d:`" VN="`echo $zeile | cut -f2 -d:`" # usw. done
*boerks*
(du meintest uebrigens '-d;', nicht '-d:'...
Jaha, dann vorsichtshalber gequoted: -d';' (ich weiss nicht, obs not tut, aber bei nem ; bin ich mal vorsichtig).
Uebrigens: ich habe die Erfahrung gemacht, dass obige Quotingweise falsch ist, wenn z.B. Leerzeichen auftauchen, richtig ist:
BK=`echo "$zeile" | ...`
Die "geechote" Variable muss gequotet werden, die `` nicht.
Eben nicht. Dem echo ist es nämlich egal, wie viele Argumente er kriegt, und mir als Nutzer des echo ist es ebenfalls schnurz, wie viele Argumente der echo't. Was aber _nicht_ egal ist, dass ist der Umstand, dass die Zuweisung BK=... nur bis zum ersten Blank funktionuckelt. Deshalb würde ich die "" gerne da lassen, wo ich sie hatte ;-)
Dann eher noch:
==== sed 's/ /_/g' < $DBFILE | \
*grrr* genau das wollte ich die ganze Zeit verhindern. Dann sind die Blanks weg, und das Rekonstruieren klappt nur dann, wenn ich sicher sein kann, dass es im Originaltext keine _ gab. Der sed ist nebenbei gesagt in Deinem folgenden Beispiel auch gar nicht notwendig. Der read holt sich die Zeile bis zum Linefeed und anschliessend haben durch das Umsetzen von IFS eh alle Leerzeichen verloren.
while read zeile do OIFS="$IFS"; IFS=";" set -- $zeile ## nein, $zeile darf hier nicht gequotet werden! IFS="$OIFS" BK="$1"; VN="$2"; NN="$3"; ST="$4"; HN="$5"; WO="$6" PL="$7" VWP="$8"; TP="$9"; VWG="${10}"; TG="${11}"; VWF="${12}" # ... done ====
Zur Erinnerung: einen externen Prozess aufzurufen ist "teuer". Und das pro Zeile einmal pro Variable duerfte dir die Performance recht deutlich versauen. [...]
Das ist richtig, deshalb würde ich privat immer dem awk oder perl den Vorzug geben. Mir ist persönlich nur das IFS-Geschubse nicht sehr sympathisch, aber das ist tiefster IMHO- Modus ;-) BTW: Geht denn das, Positionsparameter $10 usw.? Brauchen wir da nicht ein wenig Shifterei? Jan
Hallo, On Wed, 18 Sep 2002, Jan Trippler wrote:
On 18 Sep 2002 at 5:43, David Haller wrote:
On Tue, 17 Sep 2002, Jan Trippler wrote: [...]
#!/bin/bash DBFILE="telefonliste.txt"
cat $DBFILE | while read zeile; do BK="`echo $zeile | cut -f1 -d:`" VN="`echo $zeile | cut -f2 -d:`" # usw. done
*boerks*
(du meintest uebrigens '-d;', nicht '-d:'...
Jaha, dann vorsichtshalber gequoted: -d';' (ich weiss nicht, obs not tut, aber bei nem ; bin ich mal vorsichtig).
Aeh, ja klar :) Muss man quoten.
Uebrigens: ich habe die Erfahrung gemacht, dass obige Quotingweise falsch ist, wenn z.B. Leerzeichen auftauchen, richtig ist:
BK=`echo "$zeile" | ...`
Die "geechote" Variable muss gequotet werden, die `` nicht.
Eben nicht. Dem echo ist es nämlich egal, wie viele Argumente er kriegt, und mir als Nutzer des echo ist es ebenfalls schnurz, wie viele Argumente der echo't. Was aber _nicht_ egal ist, dass ist der Umstand, dass die Zuweisung BK=... nur bis zum ersten Blank funktionuckelt. Deshalb würde ich die "" gerne da lassen, wo ich sie hatte ;-)
$ touch oberboerks $ foo="bla : bla fasel;: *boerks*" $ bar="`echo $foo | cut -d':' -f3`" $ echo "'$bar'" ' oberboerks' $ bar=`echo "$foo" | cut -d':' -f3` $ echo "'$bar'" ' *boerks*' Merkst du was? Und ja, die bash interpretiert das `` als ein "Token", das quoten ist ueberfluessig, die Leerzeichen ueberlebens sowieso, aber andere Metazeichen nur, wenn das echo-Argument gequoted wird.
Dann eher noch:
==== sed 's/ /_/g' < $DBFILE | \
*grrr* genau das wollte ich die ganze Zeit verhindern. Dann sind die Blanks weg, und das Rekonstruieren klappt nur dann, wenn ich sicher sein kann, dass es im Originaltext keine _ gab. Der sed ist nebenbei gesagt in Deinem folgenden Beispiel auch gar nicht notwendig. Der read holt sich die Zeile bis zum Linefeed und anschliessend haben durch das Umsetzen von IFS eh alle Leerzeichen verloren.
Aeh, ja klar, ich dachte, das Ersetzen sei generell gewollt, und nicht nur um die Leerzeichen fuer den naechsten "Schritt" zu maskieren. Also, dann natuerlich ohne sed ;)
while read zeile do OIFS="$IFS"; IFS=";" set -- $zeile ## nein, $zeile darf hier nicht gequotet werden! IFS="$OIFS" BK="$1"; VN="$2"; NN="$3"; ST="$4"; HN="$5"; WO="$6" PL="$7" VWP="$8"; TP="$9"; VWG="${10}"; TG="${11}"; VWF="${12}" # ... done ====
Zur Erinnerung: einen externen Prozess aufzurufen ist "teuer". Und das pro Zeile einmal pro Variable duerfte dir die Performance recht deutlich versauen. [...]
Das ist richtig, deshalb würde ich privat immer dem awk oder perl den Vorzug geben. Mir ist persönlich nur das IFS-Geschubse nicht sehr sympathisch, aber das ist tiefster IMHO- Modus ;-)
Oh, IFS ist sehr praktisch und ein sehr probates Mittel. Bsp: $ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd`; echo "$7"; IFS="$OIFS" /bin/bash Auch nett: $ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd`; for i; do echo "'$i'"; done"; IFS="$OIFS" (das '^dh' jew. durch dem eigenen Usernamen ersetzen) Oder (aus /var/lib/texmf/web2c/mktexnam): OIFS=$IFS;IFS=$SEP set x `kpsewhich --expand-path='$TEXMF/fonts'"$SEP$MT_VARTEXFONTS"` shift; IFS=$OIFS for i do test -z "$i" && continue case "$fullname" in $i/*) [..] esac done
BTW: Geht denn das, Positionsparameter $10 usw.?
Na klar geht das, man muss aber ${nn} verwenden, da die bash sonst aus $13 ein ${1}3 macht. $ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd; grep '^dh' /etc/passwd`; echo "'$1' '$13' '${13}'"; IFS="$OIFS" 'dh' 'dh3' '/bin/bash'
Brauchen wir da nicht ein wenig Shifterei?
Noe. Obiges war getestet. Shiften ginge aber natuerlich auch. -dnh -- "We demand rigidly defined areas of doubt and uncertainty!" -- Vroomfondel
On 18 Sep 2002 at 20:59, David Haller wrote: [...]
$ touch oberboerks $ foo="bla : bla fasel;: *boerks*" $ bar="`echo $foo | cut -d':' -f3`" $ echo "'$bar'" ' oberboerks'
Wirkt etwas konstruiert, der Plot ;-) Aber klar: Shell-Sonderzeichen hatte ich erfolgreich verdrängt, sowas muss gequoted werden.
$ bar=`echo "$foo" | cut -d':' -f3` $ echo "'$bar'" ' *boerks*'
Merkst du was? Und ja, die bash interpretiert das `` als ein "Token", das quoten ist ueberfluessig, die Leerzeichen ueberlebens sowieso, aber andere Metazeichen nur, wenn das echo-Argument gequoted wird.
*Verwirrt den Kopf kratz* Nanu - das hatte ich doch anders in Erinnerung. Werde ich etwa senil? jan@p4mobil:~/devel/tests> touch "x y" jan@p4mobil:~/devel/tests> a="x y" jan@p4mobil:~/devel/tests> ls `echo "$a"` ls: x: Datei oder Verzeichnis nicht gefunden ls: y: Datei oder Verzeichnis nicht gefunden jan@p4mobil:~/devel/tests> ls "`echo $a`" x y Ah, _sowas_ meinte ich :-) Merkwürdig - die Zuweisung an Variablen scheint nach anderen Gesetzen zu laufen. Kann es sein, dass bash-Interna da andere Wege gehen als der normalsterbliche Linux-Befehl? Das werde ich morgen mal unter Solaris testen.
Oh, IFS ist sehr praktisch und ein sehr probates Mittel. Bsp:
$ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd`; echo "$7"; IFS="$OIFS" /bin/bash
Hmm: grep '^dh' /etc/passwd | cut -f7 -d: oder: awk -F : ' /^dh/ { print $7 } ' /etc/passwd sind mir persönlich lieber, aber wie gesagt: IMHO-Modus. Ich kann im ersten Moment auch nicht erkennen, welche Vorteile mir die IFS-Version bringt.
Auch nett:
$ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd`; for i; do echo "'$i'"; done"; IFS="$OIFS" ^^ typo!
grep '^jan' /etc/passwd | tr ':' '\n' Ich habe das Umbauen von IFS auch schon verwendet, konnte mich aber nie so richtig damit anfreunden und nehme wenn möglich was anderes. In Scripts sehe ich den Einsatz von set -- eh kritisch, weil ich mir damit u. U. die Original- Parameter überschreibe.
BTW: Geht denn das, Positionsparameter $10 usw.?
Na klar geht das, man muss aber ${nn} verwenden, da die bash sonst aus $13 ein ${1}3 macht.
Gucke da, ich habe bisher (hatte ich mal so gelernt) immer brav shift gemacht. Noch ein Fall für meinen Solaris-Test ;-) Jan
Hallo, On Thu, 19 Sep 2002, Jan Trippler wrote:
On 18 Sep 2002 at 20:59, David Haller wrote: [...]
$ touch oberboerks $ foo="bla : bla fasel;: *boerks*" $ bar="`echo $foo | cut -d':' -f3`" $ echo "'$bar'" ' oberboerks'
Wirkt etwas konstruiert, der Plot ;-)
Aber natuerlich ist der konstruiert. Denn an den Fall wo ich drueber gestolpert bin erinnere ich mich leider nicht mehr.
Aber klar: Shell-Sonderzeichen hatte ich erfolgreich verdrängt, sowas muss gequoted werden.
Jep.
$ bar=`echo "$foo" | cut -d':' -f3` $ echo "'$bar'" ' *boerks*'
Merkst du was? Und ja, die bash interpretiert das `` als ein "Token", das quoten ist ueberfluessig, die Leerzeichen ueberlebens sowieso, aber andere Metazeichen nur, wenn das echo-Argument gequoted wird.
*Verwirrt den Kopf kratz* Nanu - das hatte ich doch anders in Erinnerung. Werde ich etwa senil?
jan@p4mobil:~/devel/tests> touch "x y" jan@p4mobil:~/devel/tests> a="x y" jan@p4mobil:~/devel/tests> ls `echo "$a"` ls: x: Datei oder Verzeichnis nicht gefunden ls: y: Datei oder Verzeichnis nicht gefunden jan@p4mobil:~/devel/tests> ls "`echo $a`" x y
*Verwirrt den Kopf kratz*
Ah, _sowas_ meinte ich :-) Merkwürdig - die Zuweisung an Variablen scheint nach anderen Gesetzen zu laufen. Kann es sein, dass bash-Interna da andere Wege gehen als der normalsterbliche Linux-Befehl?
Moeglich waere's. Hm. Mompl. $ cd /tmp/test/kranke_dateinamen $ for f in *; do ls -lb `echo "$f"` done [nur: no such file...] $ for f in *; do ls -lb "`echo $f`"; done Immerhin 5 von 6: Fehler beim (von mir hier jetzt mit [] umschlossenen Dateinamen(!): ["foo" and "bar"] (mit ls -b wird '\n' statt Umbruch angezeigt). Der Witz ist aber die Fehlermeldung: ls: "foo"\ and\ "bar": No such file or directory *kopfkratz und duemmlich grins* $ for f in *; do a=`echo "$f"`; ls -lb "$a"; done [alle 6 korrekt] Offenbar wird eine Variablenzuweisung anders expandiert, als wenn als Argument an ls uebergeben... Auch korrekt klappt: $ for f in *; do ls -lb "`echo \"$f\"`"; done Apropos: die Darstellung im mc verrupfts deftig in dem Ordner *eg*, und dabei hab ich ein paar fiese sogar wieder geloescht... Hm. Ich muss da mal wieder ein paar "gute" Dateinamen ergaenzen ;) Hm. Was lernen wir beide nun (und vielleicht der eine oder andere auch) daraus? Quoten bis der Arzt kommt... Wobei's ja bei Variablenzuweiseungen "weniger" braucht als als Argument fuer einen Befehl...
Das werde ich morgen mal unter Solaris testen.
Mach das ;)
Oh, IFS ist sehr praktisch und ein sehr probates Mittel. Bsp:
$ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd`; echo "$7"; IFS="$OIFS" /bin/bash
Hmm: grep '^dh' /etc/passwd | cut -f7 -d: oder: awk -F : ' /^dh/ { print $7 } ' /etc/passwd
sind mir persönlich lieber, aber wie gesagt: IMHO-Modus. Ich kann im ersten Moment auch nicht erkennen, welche Vorteile mir die IFS-Version bringt.
Der Vorteil stellt sich ein, wenn man mit mehreren Feldern was basteln will, da faellt dann weg x-fach ein grep | cut / awk zu verwenden, sondern man hat alle Felder direkt in _shell_-Variablen. Wenn man "nur" in awk oder perl bleibt laesst sich das natuerlich auch leicht erreichen, in perl waere das z.B.: my ($login, $x, $uid, $gid, $fullname, $home, $shell) = split(':', $_); Ok, via set hat man nicht gleich so schoene Variablennamen ;)
Auch nett:
$ OIFS="$IFS"; IFS=":"; set -- `grep '^dh' /etc/passwd`; for i; do echo "'$i'"; done"; IFS="$OIFS" ^^ typo! Ja, das '"' ist zuviel.
grep '^jan' /etc/passwd | tr ':' '\n'
Oeh, ja, nur kann man halt mit dem $i ein wenig mehr anfangen als mit der Ausgabe des tr... Siehe wie gesagt z.B. mktexupd. Das Beispiel mit der passwd ist sowieso eher weniger gut; besser (einleuchtender) ist wohl: $ OIFS="$IFS"; IFS=":"; \ for p in $PATH; do \ test -L "${p}/vim" && readlink "${p}/vim"; \ done; \ IFS="$OIFS" (wobei der Schleifenkoerper wieder nur ein eher "dummes" Beispiel ist). Variablen mit ':' als Pfadtrenner gibt's ja noch mehr, z.B. LD_LIBRARY_PATH, MANPATH, INFO{PATH,DIR}...
Ich habe das Umbauen von IFS auch schon verwendet, konnte mich aber nie so richtig damit anfreunden und nehme wenn möglich was anderes.
In Scripts sehe ich den Einsatz von set -- eh kritisch, weil ich mir damit u. U. die Original- Parameter überschreibe.
Wo ist das Problem? ARGV="$@"; OIFS="$IFS"; IFS=":" set -- `grep '^name' /etc/pwasswd` IFS="$OIFS" # mach was mit $@ set -- $ARGV
BTW: Geht denn das, Positionsparameter $10 usw.?
Na klar geht das, man muss aber ${nn} verwenden, da die bash sonst aus $13 ein ${1}3 macht.
Gucke da, ich habe bisher (hatte ich mal so gelernt) immer brav shift gemacht. Noch ein Fall für meinen Solaris-Test ;-)
*bg* -dnh -- A common mistake that people make, when trying to design something completely foolproof is to underestimate the ingenuity of complete fools. -- Douglas Adams - Mostly Harmless
Moin, On Don, 19 Sep 2002 at 23:52 (+0200), David Haller wrote: [...]
Auch korrekt klappt: $ for f in *; do ls -lb "`echo \"$f\"`"; done
Jau, das wäre jetzt auch meine finale Version gewesen.
Apropos: die Darstellung im mc verrupfts deftig in dem Ordner *eg*, und dabei hab ich ein paar fiese sogar wieder geloescht... Hm. Ich muss da mal wieder ein paar "gute" Dateinamen ergaenzen ;)
Was lernen wir daraus? ls und Co. sind und bleiben die einzig wahren Tools :-)
Das werde ich morgen mal unter Solaris testen.
Mach das ;)
Vergessen :-( Ich hatte einen üblen Bug in einem Mini-Http-Server zu finden (aber das ist eine andere Geschichte und soll ein anderes Mal erzählt werden ;-) und deshalb keine Zeit zum Spielen. [IFS-Beispiele]
Der Vorteil stellt sich ein, wenn man mit mehreren Feldern was basteln will, da faellt dann weg x-fach ein grep | cut / awk zu verwenden, sondern man hat alle Felder direkt in _shell_-Variablen. Wenn man "nur" in awk oder perl bleibt laesst sich das natuerlich auch leicht erreichen, in perl waere das z.B.:
my ($login, $x, $uid, $gid, $fullname, $home, $shell) = split(':', $_);
my ($login, $x, $uid, $gid, $fullname, $home, $shell) = split /:/; finde ich schicker ;-)
Ok, via set hat man nicht gleich so schoene Variablennamen ;)
wenn man die in Perl nicht braucht, gehts noch fixer: my @passwd = split /:/; [...]
$ OIFS="$IFS"; IFS=":"; \ for p in $PATH; do \ test -L "${p}/vim" && readlink "${p}/vim"; \ done; \ IFS="$OIFS"
Ja, sowas ist nett. [...]
In Scripts sehe ich den Einsatz von set -- eh kritisch, weil ich mir damit u. U. die Original- Parameter überschreibe.
Wo ist das Problem?
ARGV="$@"; OIFS="$IFS"; IFS=":" set -- `grep '^name' /etc/pwasswd` IFS="$OIFS" # mach was mit $@ set -- $ARGV
Das finde ich eher nicht so toll, vor allem, wenn das Script nicht stur geradeaus verläuft. IMHO macht man sich damit das Leben schwerer als es Erleichterungen bringt. Aber Du hast natürlich recht: Es ist eine interessante Technik und man sollte IFS im Hinterkopf behalten, wenn man auf ähnlich gelagerte Probleme stößt. Im übrigen gelten auch hier wieder diese dämlichen Sprichwörter *Viele Wege führen nach Rom* und *Wat dem eenen sin Uhl is dem annern sin Nachtigall* (spell?) Jan
participants (3)
-
David Haller
-
Fred Kastl
-
Jan.Trippler@t-online.de