PDA

View Full Version : Question About Shell For Loop



huangyingw
January 27th, 2010, 02:31 PM
Hello,
I have two questions about shell "for loop".
one is


for ((i = 0;i<=5;i++))
do
echo "Welcome $i times"
done

I got
Syntax error: Bad for loop variable
I don't know why this happen.:(
And this one:


dir=/root/myproject/git/folder/
for file in "`find ${dir} -type f`";
do
echo \n prefix${file}
done

I got
prefix/root/myproject/git/folder/aidaz03a047.jpg /root/myproject/git/folder/aidaz04z020.jpg /root/myproject/git/folder/anna02a035.jpg
Instead, I would like each of the $(file) would be added with a prefix. And even using \n option, I did not get the expected effect of one line for each words.:(

kaibob
January 27th, 2010, 03:12 PM
Hello,
I have two questions about shell "for loop".
one is


for ((i = 0;i<=5;i++))
do
echo "Welcome $i times"
done

I got
Syntax error: Bad for loop variable
I don't know why this happen.:(


This works for me with bash. What shell are you using? It won't work with the dash shell.

huangyingw
January 27th, 2010, 03:33 PM
This works for me with bash. What shell are you using? It won't work with the dash shell.
Hi, how could I know what is the shell I am using? The whole of my for.sh is shown as bellow:


#! /bin/sh
dir=/root/myproject/git/folder/
for file in "`find ${dir} -type f`";
do
echo \n prefix${file}
done

#for ((i = 0;i<=5;i++))
#do
# echo "Welcome $i times"
#done

kaibob
January 27th, 2010, 03:40 PM
And this one:


dir=/root/myproject/git/folder/
for file in "`find ${dir} -type f`";
do
echo \n prefix${file}
done

I got
prefix/root/myproject/git/folder/aidaz03a047.jpg /root/myproject/git/folder/aidaz04z020.jpg /root/myproject/git/folder/anna02a035.jpg
Instead, I would like each of the $(file) would be added with a prefix. And even using \n option, I did not get the expected effect of one line for each words.:(

I would rewrite this script as follows:


#!/bin/bash

dir="/target/directory"

find "${dir}" -type f | while read file ; do
echo "prefix${file}"
done

I'm not certain, but I believe your script sees the output of the find command as one long string. You could fix this by removing the quotes around the find command, but the script would still break if any filenames contained spaces. This could be fixed by resetting the IFS as follows:


#!/bin/bash

IFS=$'\n'

dir=/target/directory

for file in $(find ${dir} -type f) ; do
echo prefix${file}
done

BTW, #!/bin/bash refers to the bash shell and #!/bin/sh is the dash shell. To see the difference:

https://wiki.ubuntu.com/DashAsBinSh

wmcbrine
January 27th, 2010, 04:10 PM
I think a more traditional sh (as opposed to pseudo-C) way to do the numeric loop would be "for i in seq 5".

denarced
January 27th, 2010, 05:11 PM
When it is your purpose to execute something(echo,mv,cp...) based on what the find-command has produced, I find it best to use the find-commands own execute action. It'd look like this in your case:


#!/bin/bash

dir='/root/myproject/git/folder/'
find $dir -type f -exec echo prefix'{}' \;

huangyingw
January 29th, 2010, 03:48 PM
I would rewrite this script as follows:

Yes, thank you. My quotes around the find command is try to prevent the white space as you guess.
thanks for your example of while loop, which is quite very useful.

huangyingw
January 29th, 2010, 03:49 PM
When it is your purpose to execute something(echo,mv,cp...) based on what the find-command has produced, I find it best to use the find-commands own execute action. It'd look like this in your case:


#!/bin/bash

dir='/root/myproject/git/folder/'
find $dir -type f -exec echo prefix'{}' \;

Yes, thanks for your best solution.