[opensuse] Shell question> for a in $( find [...] )
Hi, I'm busy writing a script that does 'something' with every file found. It does something like: for a in $( find /mnt/Data/Todo -type f -exec basename {} \; ); do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done The problem here is simply: it works only as long as the filename does not contain any whitechars :( Is there a good way to get around this? Thanks for your pointers. Dominique -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Dominique Leuenberger wrote:
Hi,
I'm busy writing a script that does 'something' with every file found.
It does something like:
for a in $( find /mnt/Data/Todo -type f -exec basename {} \; ); do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
The problem here is simply: it works only as long as the filename does not contain any whitechars :(
Is there a good way to get around this?
Put $a in double qoutes. /Per -- Per Jessen, Zürich (13.7°C) -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On 4/21/2009 at 11:37, Per Jessen <per@opensuse.org> wrote: Dominique Leuenberger wrote:
Hi,
I'm busy writing a script that does 'something' with every file found.
It does something like:
for a in $( find /mnt/Data/Todo -type f -exec basename {} \; ); do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
The problem here is simply: it works only as long as the filename does not contain any whitechars :(
Is there a good way to get around this?
Put $a in double qoutes.
Per, that solution was to easy and of course is not true (the original script actually has them quoted) The problem happens in line for a already where 'for' is splitting the array of chars at the white chars. Dominique -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Dominique Leuenberger wrote:
On 4/21/2009 at 11:37, Per Jessen <per@opensuse.org> wrote: Dominique Leuenberger wrote:
Hi,
I'm busy writing a script that does 'something' with every file found.
It does something like:
for a in $( find /mnt/Data/Todo -type f -exec basename {} \; ); do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
The problem here is simply: it works only as long as the filename does not contain any whitechars :(
Is there a good way to get around this?
Put $a in double qoutes.
Per, that solution was to easy and of course is not true (the original script actually has them quoted)
The problem happens in line for a already where 'for' is splitting the array of chars at the white chars.
I guess it I didn't take enough time to read through everything, sorry. How about this slightly changed script: (not tested) find /mnt/Data/Todo -type f -exec basename {} \; | while read a do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done /Per -- Per Jessen, Zürich (14.6°C) -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On 4/21/2009 at 11:51, Per Jessen <per@opensuse.org> wrote: find /mnt/Data/Todo -type f -exec basename {} \; | while read a do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
Per, you're my hero of the day! Thank you very much for this very prompt response. Next time I'm in Zurich we go for a drink! (should not happen to rarely. I normally fly in via Zurich). Dominique -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Tue, Apr 21, 2009 at 11:51:01AM +0200, Per Jessen wrote:
Dominique Leuenberger wrote:
On 4/21/2009 at 11:37, Per Jessen <per@opensuse.org> wrote: Dominique Leuenberger wrote:
Hi,
I'm busy writing a script that does 'something' with every file found.
It does something like:
for a in $( find /mnt/Data/Todo -type f -exec basename {} \; ); do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
The problem here is simply: it works only as long as the filename does not contain any whitechars :(
Is there a good way to get around this?
Put $a in double qoutes.
Per, that solution was to easy and of course is not true (the original script actually has them quoted)
The problem happens in line for a already where 'for' is splitting the array of chars at the white chars.
I guess it I didn't take enough time to read through everything, sorry. How about this slightly changed script: (not tested)
find /mnt/Data/Todo -type f -exec basename {} \; | while read a do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
shopt -s globstar OIFS="$IFS" IFS=$'\n' for a in /mnt/Data/Todo/** ; do test -f "$a" || continue a="${a##*/}" /usr/bin/stcommand "$a" /usr/bin/2ndcommand "$a" done IFS="$OIFS" ... OK the `**' trick for listing subdirectories works only for bash 4.0 ... for a plain directory simply use `*' ... on the other hand the GNU find also shows an option -printf: find /mnt/Data/Todo/ -type f -printf '%f\n' to avoid the `-exec {} \;' Werner -- "Having a smoking section in a restaurant is like having a peeing section in a swimming pool." -- Edward Burr -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On 4/21/2009 at 12:12, "Dr. Werner Fink" <werner@suse.de> wrote:
shopt -s globstar OIFS="$IFS" IFS=$'\n' for a in /mnt/Data/Todo/** ; do test -f "$a" || continue a="${a##*/}" /usr/bin/stcommand "$a" /usr/bin/2ndcommand "$a" done IFS="$OIFS"
... OK the `**' trick for listing subdirectories works only for bash 4.0 ... for a plain directory simply use `*' ... on the other hand the GNU find also shows an option -printf:
Werner, This actually looks like a nice alternative solution. for gnu find I tried playing with it; setting IFS might have been enough in my script too. I keep on forgetting this. Anyhow, thank you very much. It's always a pleasure to see the different approaches that are possible. Dominique -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
In <gsk4u5$5a8$1@saturn.local.net>, Per Jessen wrote:
find /mnt/Data/Todo -type f -exec basename {} \; | while read a do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
This falls down when filenames contain back-slashes (sometimes) or newlines. Using 'read -r a' falls down when filenames contain newlines. -- Boyd Stephen Smith Jr. ,= ,-_-. =. bss@iguanasuicide.net ((_/)o o(\_)) ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-' http://iguanasuicide.net/ \_/
On 4/21/2009 at 17:13, "Boyd Stephen Smith Jr." <bss@iguanasuicide.net> wrote:
In find /mnt/Data/Todo -type f -exec basename {} \done This falls down when filenames contain back-slashes (sometimes) or newlines. Using 'read -r a' falls down when filenames contain newlines. --
I can live with that ;) The users create the files on a Windows box and as such, wjitespaces are common, newlines probably not and backslashes are not valid neither in this world. So Those shortcomings are acceptable (considering on how much more readable it is). Thanks anyway! I'll keep this around. Dominique -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Per Jessen wrote:
Dominique Leuenberger wrote:
On 4/21/2009 at 11:37, Per Jessen <per@opensuse.org> wrote:
Dominique Leuenberger wrote:
Hi,
I'm busy writing a script that does 'something' with every file found.
It does something like:
for a in $( find /mnt/Data/Todo -type f -exec basename {} \; ); do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
The problem here is simply: it works only as long as the filename does not contain any whitechars :(
Is there a good way to get around this?
Put $a in double qoutes.
Per, that solution was to easy and of course is not true (the original script actually has them quoted)
The problem happens in line for a already where 'for' is splitting the array of chars at the white chars.
I guess it I didn't take enough time to read through everything, sorry. How about this slightly changed script: (not tested)
find /mnt/Data/Todo -type f -exec basename {} \; | while read a do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
Rather, set -f find /path/to/stuff -type f | while read do { a="${REPLY##*/}" something "$a" else "$a" } </dev/null done Otherwise it only works if you happen to be lucky and none of the commands happens to read stdin. Never rely on luck or assume that something is right just because you tried it and it worked. Also, less important, spawning a process every iteration just for basename is unnecessary. But note the real way is to find out what the commands actually are and how they behave and what the ultimate goal is and probably determine that a while read loop is probably wrong in the first place, in favor of "find -print0 |xargs -0" and thereby not care what crazy characters might be in the names. ... and I see someone else already posted exactly the part I didn't want to stop to figure out, how to use a list of commands as the argument to xargs. THAT is by far the most correct and robust approach even if, being untested, Boyd's off the cuff sample turns out to need adjusting to work. -- bkw -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
In <49EDAA4702000029000180A4@mail2.tmf-group.com>, Dominique Leuenberger wrote:
Hi,
I'm busy writing a script that does 'something' with every file found.
It does something like:
for a in $( find /mnt/Data/Todo -type f -exec basename {} \; ); do /usr/bin/stcommand $a /usr/bin/2ndcommand $a done
The problem here is simply: it works only as long as the filename does not contain any whitechars :(
Is there a good way to get around this?
find /mnt/Data/Todo -type f -print0 | xargs -r0 -- /bin/sh -c 'for a in "$@"; do a=$(basename "$a"); /usr/bin/stcommand "$a"; /usr/bin/2ndcommand "$a"; done' That's untested, but I believe it will work. It might have an off-by-one issue though. -- Boyd Stephen Smith Jr. ,= ,-_-. =. bss@iguanasuicide.net ((_/)o o(\_)) ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-' http://iguanasuicide.net/ \_/
participants (5)
-
Boyd Stephen Smith Jr.
-
Brian K. White
-
Dominique Leuenberger
-
Dr. Werner Fink
-
Per Jessen