Hallo ich hab hier so ein scriptchen das etwas mit jeder Datei macht die es in einem Verzeichnis gibt. Darin kommt folgendes vor: for x in `ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq` ; do ... done funktioniert soweit perfekt, AUSSER wenn ein filename einen leerschlag enthält, zB "test file.txt" dann wird "test" und "file.txt" separat behandelt... Was kann ich dagegen tun? Danke! Matti
Hallo, Am Sun, 19 Jun 2005, Andreas Loesch schrieb:
Am Sonntag, 19. Juni 2005 22:15 schrieb Matthias Keller:
for x in `ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq` ;
quote mal die Dateinamen, also
for x in "`ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq`" ;
Das packt alle Dateinamen zusammen in ein x. -dnh -- "I think there is a world market for maybe five computers." -- Thomas Watson, chairman of IBM, 1943.
On Sun, Jun 19, 2005 at 10:15:57PM +0200, Matthias Keller wrote:
for x in `ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq` ; do ... done
funktioniert soweit perfekt, AUSSER wenn ein filename einen leerschlag enthält, zB "test file.txt" dann wird "test" und "file.txt" separat behandelt...
Mit einer while Schleife: ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq | while IFS= read i do ... done /GM
Hallo, Am Mon, 20 Jun 2005, Gerhard Meier schrieb:
On Sun, Jun 19, 2005 at 10:15:57PM +0200, Matthias Keller wrote:
for x in `ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq` ; do ... done
funktioniert soweit perfekt, AUSSER wenn ein filename einen leerschlag enthält, zB "test file.txt" dann wird "test" und "file.txt" separat behandelt...
Mit einer while Schleife:
ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq | while IFS= read i do ... done
Es soll explizit an Newlines getrennt werden, also sollte man das prinzipiell auch machen ( IFS=" "). Allerdings liest 'read' sowieso zeilenweise. ls "$path/" | sed -e 's/\.dd-.*$//' | uniq | while read -r name do echo "$name" done Oder eben explizit: ls "$path/" | sed -e 's/\.dd-.*$//' | uniq | while IFS=" " read -r name do echo "$name" done Siehe 'help read'. Und vgl. ls "$path/" | sed -e 's/\.dd-.*$//' | uniq | while IFS="." read -r -a name do echo "${name[*]}" done -dnh -- SprintLINK makes proton decay look fast. -- Jude Charles Giampaolo
David Haller wrote:
Hallo,
Am Mon, 20 Jun 2005, Gerhard Meier schrieb:
On Sun, Jun 19, 2005 at 10:15:57PM +0200, Matthias Keller wrote:
for x in `ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq` ; do ... done
funktioniert soweit perfekt, AUSSER wenn ein filename einen leerschlag enthält, zB "test file.txt" dann wird "test" und "file.txt" separat behandelt...
Mit einer while Schleife:
ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq | while IFS= read i do ... done
Es soll explizit an Newlines getrennt werden, also sollte man das prinzipiell auch machen ( IFS=" "). Allerdings liest 'read' sowieso zeilenweise.
ls "$path/" | sed -e 's/\.dd-.*$//' | uniq | while read -r name do echo "$name" done
Hallo Leider funktioniert dies in meinem Falle nicht, da ich innerhalb des loops noch userinput verarbeite via read, was sich dann wohl irgendwie beisst so wies aussieht...? Ginge das nicht irgendwie ohne read? Danke! Matti
On Tuesday 21 June 2005 12:00, Matthias Keller wrote:
Leider funktioniert dies in meinem Falle nicht, da ich innerhalb des loops noch userinput verarbeite via read, was sich dann wohl irgendwie beisst so wies aussieht...?
Ginge das nicht irgendwie ohne read?
Schau Dir die Lösung mit der named pipe an. Die sollte in Deinem Fall auch funktionieren. Torsten
On Sunday 19 June 2005 22:15, Matthias Keller wrote:
Hallo
ich hab hier so ein scriptchen das etwas mit jeder Datei macht die es in einem Verzeichnis gibt. Darin kommt folgendes vor:
for x in `ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq` ; do ... done
funktioniert soweit perfekt, AUSSER wenn ein filename einen leerschlag enthält, zB "test file.txt" dann wird "test" und "file.txt" separat behandelt...
Alle bisher vorgeschlagenen Lösungen haben den Nachteil, dass die while-Schleife von einer Sub-Shell ausgeführt wird. Innerhalb des ursprünglichen for-Loops konnten Variablen gesetzt werden, die nach Ende des Loops noch erhalten sind. Mit der while-Lösung geht das nicht: r2@opi:~> a=0; r2@opi:~> for i in 1 2 3; do a=$i; done r2@opi:~> echo $a 3 r2@opi:~> a=0; r2@opi:~> (echo 1; echo 2; echo 3) | while read i; do a=$i; done r2@opi:~> echo $a 0 <== hier hätte der Unbedarfte auch 3 erwartet Die Variable a wird nur in der Sub-Shell verändert. Die Lösung, die mir dazu einfällt ist ein bisschen kompliziert. Vielleicht kennt jemand eine bessere: r2@opi:~> a=0 r2@opi:~> mkfifo fifo r2@opi:~> (echo 1; echo 2; echo 3) >fifo & [1] 4555 r2@opi:~> while read i <fifo; do a=$i; done [1]+ Done ( echo 1; echo 2; echo 3 ) >fifo r2@opi:~> echo $a 3 Hier wird eine named pipe benutzt. Das read-Kommando liest aus der Pipe. Die while-Schleife läuft damit in der Haupt-Shell. Entsprechend wäre die exakte Lösung des Problems: ls -1 $path/ | sed -e 's/\.dd-.*$//' | uniq >fifo & while read i <fifo; do ... done Torsten
Hallo Torsten, hallo Leute, Am Montag, 20. Juni 2005 22:31 schrieb Torsten Foertsch: [...]
Alle bisher vorgeschlagenen Lösungen haben den Nachteil, dass die while-Schleife von einer Sub-Shell ausgeführt wird. Innerhalb des ursprünglichen for-Loops konnten Variablen gesetzt werden, die nach Ende des Loops noch erhalten sind. [...] Die Variable a wird nur in der Sub-Shell verändert.
Die Lösung, die mir dazu einfällt ist ein bisschen kompliziert. [Verwendung einer named pipe]
Vielleicht kennt jemand eine bessere:
Es geht auch ohne named pipe - ich würde es aber trotzdem als "ein bisschen komplizert" betrachten ;-) http://www.cboltz.de/de/linux/bash/?sl Gruß Christian Boltz -- "Anybody who really thinks /bin/true should report a version number and a help string (or even a copyright notice) needs to get his head examined." [Linus Torvalds]
Hallo Christian, On Wednesday 22 June 2005 00:56, Christian Boltz wrote:
Sowas hatte ich auch schon mal geschrieben. Mit dem eval muss man aber genau aufpassen, was man den Variablen zuweist und evtl. Sonderzeichen quoten. In Deinen Absatz über PIPESTATUS könntest Du noch "set -o pipefail" aufnehmen. Aus "help set": pipefail the return value of a pipeline is the status of the last command to exit with a non-zero status, or zero if no command exited with a non-zero status Der Effekt ist folgender: r2@opi:~> { true|false|true; } && echo ok ok r2@opi:~> set -o pipefail r2@opi:~> { true|false|true; } && echo ok r2@opi:~> Die named pipe-Lösung wäre auf der Seite sicher auch gut untergebracht. Torsten
participants (6)
-
Andreas Loesch
-
Christian Boltz
-
David Haller
-
Gerhard Meier
-
Matthias Keller
-
Torsten Foertsch