This is my directory structure:
.
| a.sh
| a.txt
|
+---foo bar
| b.txt
|
+---santa
| | c.txt
| |
| ---humpty dumpty
| e.txt
|
---test
d.txt
I want to do some operation on each file ending with .txt. However,
this script wouldn't work because in each iteration it gets one word
from the output of find.
Script:
for file in `find -name "*.txt"`
do
echo file: $file
done
You can see how ./santa/humpty dumpty/e.txt has been broken into two
iterations. Any way to resolve this?
--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
01-07-2010, 09:18 AM
Javier Barroso
Handle paths with spaces
On Thu, Jan 7, 2010 at 11:08 AM, Foss User <fossist@gmail.com> wrote:
> This is my directory structure:
> .
> | * a.sh
> | * a.txt
> |
> +---foo bar
> | * * * b.txt
> |
> +---santa
> | * | * c.txt
> | * |
> | * ---humpty dumpty
> | * * * * * e.txt
> |
> ---test
> * * * *d.txt
>
> I want to do some operation on each file ending with .txt. However,
> this script wouldn't work because in each iteration it gets one word
> from the output of find.
If you are using bash, the answer is in the faq
http://mywiki.wooledge.org/BashFAQ/020
Regards,
--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
01-07-2010, 09:19 AM
Alex Samad
Handle paths with spaces
On Thu, Jan 07, 2010 at 03:38:23PM +0530, Foss User wrote:
> This is my directory structure:
> .
> | a.sh
> | a.txt
> |
> +---foo bar
> | b.txt
> |
> +---santa
> | | c.txt
> | |
> | ---humpty dumpty
> | e.txt
> |
> ---test
> d.txt
>
> I want to do some operation on each file ending with .txt. However,
> this script wouldn't work because in each iteration it gets one word
> from the output of find.
>
> Script:
>
> for file in `find -name "*.txt"`
> do
> echo file: $file
> done
>
> Execution:
>
> $ sh a.sh
> file: ./a.txt
> file: ./foo
> file: bar/b.txt
> file: ./santa/c.txt
> file: ./santa/humpty
> file: dumpty/e.txt
> file: ./test/d.txt
>
> You can see how ./santa/humpty dumpty/e.txt has been broken into two
> iterations. Any way to resolve this?
do man bash or man sh or man dash which ever you are using and look up
IFS
oIFS="$IFS"
IFS='
'
for file in `find -name "*.txt"`
do
echo file: $file
done
IFS="$oIFS"
I think should work
>
>
--
"In other words, I don't think people ought to be compelled to make the decision which they think is best for their family."
- George W. Bush
12/11/2002
on smallpox vaccinations, Washington, D.C.
01-07-2010, 09:37 AM
Jon Dowland
Handle paths with spaces
On Thu, Jan 07, 2010 at 03:38:23PM +0530, Foss User wrote:
> I want to do some operation on each file ending with .txt. However,
> this script wouldn't work because in each iteration it gets one word
> from the output of find.
Did you read my reply to your last question?
<http://lists.debian.org/debian-user/2010/01/msg00403.html>
Look at the -print0 arg for find and the -0 argument for
xargs.
> Script:
>
> for file in `find -name "*.txt"`
> do
> echo file: $file
> done
You need to quote $file here:
echo file: "$file"
As described in another reply to your last thread,
<http://lists.debian.org/debian-user/2010/01/msg00267.html>
Please ensure you carefully read the replies people have
already written.
--
Jon Dowland
01-07-2010, 03:35 PM
Bob McGowan
Handle paths with spaces
Jon Dowland wrote:
> On Thu, Jan 07, 2010 at 03:38:23PM +0530, Foss User wrote:
>> I want to do some operation on each file ending with .txt. However,
>> this script wouldn't work because in each iteration it gets one word
>> from the output of find.
>
> Did you read my reply to your last question?
> <http://lists.debian.org/debian-user/2010/01/msg00403.html>
>
> Look at the -print0 arg for find and the -0 argument for
> xargs.
Doesn't work - bash and the 'for' loop work on newline terminated
strings and don't know how to handle the null terminator from -print0:
$ find . -name '*txt'
./a b/tst.txt
./c/tst2.txt
$ for n in $(find . -name '*txt')
> do
> echo $n
> done
./a
b/tst.txt
./c/tst2.txt
$ for n in $(find . -name '*txt' -print0)
> do
> echo $n
> done
./a
b/tst.txt
$
In the third 'find' command with -print0, only one file is found, and it
is still split on the space.
>
>> Script:
>>
>> for file in `find -name "*.txt"`
>> do
>> echo file: $file
>> done
>
> You need to quote $file here:
> echo file: "$file"
>
> As described in another reply to your last thread,
> <http://lists.debian.org/debian-user/2010/01/msg00267.html>
>
> Please ensure you carefully read the replies people have
> already written.
>
>
Generally a good idea to quote the variable, but in this case it won't
help, the split on spaces has happened before the arguments get to the
'echo'.
I would suggest to the OP that they use a 'while' loop rather than 'for':
find . -name '*txt' |
while read n
do
echo "$n"
done
./a b/tst.txt
./c/tst2.txt
The 'read' gets the whole line, ignoring spaces.
--
Bob McGowan
--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
01-08-2010, 01:00 AM
"Boyd Stephen Smith Jr."
Handle paths with spaces
In <3f8297b21001070208q640b8abdudc0bda752f8877e1@mail .gmail.com>, Foss User
wrote:
>This is my directory structure:
>.
>| a.sh
>| a.txt
>+---foo bar
>| b.txt
>+---santa
>| | c.txt
>| ---humpty dumpty
>| e.txt
>---test
> d.txt
>
>I want to do some operation on each file ending with .txt.
>
>Script:
>
>for file in `find -name "*.txt"`
Backticks aren't magic. They don't understand the output of the command
within, they simply break on whitespace.[1]
If using GNU find, you can use fewer processes by using a '+' instead of a ':'
and having the shell script (the part in single quotes) handle multiple
arguments.
[1] It's actually a bit more complex than that. Look for documentation on
word-splitting for your favorite shell.
--
Boyd Stephen Smith Jr. ,= ,-_-. =.
bss@iguanasuicide.net ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-'
http://iguanasuicide.net/ \_/
01-08-2010, 01:07 AM
"Boyd Stephen Smith Jr."
Handle paths with spaces
In <4B460D6C.3050007@symantec.com>, Bob McGowan wrote:
>Jon Dowland wrote:
>> On Thu, Jan 07, 2010 at 03:38:23PM +0530, Foss User wrote:
>>> I want to do some operation on each file ending with .txt. However,
>>> this script wouldn't work because in each iteration it gets one word
>>> from the output of find.
>>
>> Did you read my reply to your last question?
>> <http://lists.debian.org/debian-user/2010/01/msg00403.html>
>>
>> Look at the -print0 arg for find and the -0 argument for
>> xargs.
>
>Doesn't work - bash and the 'for' loop work on newline terminated
>strings and don't know how to handle the null terminator from -print0:
Yes, that's why he mentioned the -0 option to xargs. If you are using -print0
with find, you'll probably want to pipe in into xargs -0.
(find -type f -print0 | xargs -0 -- grep -i foo --) for example.
>>> Script:
>>>
>>> for file in `find -name "*.txt"`
>>> do
>>> echo file: $file
>>> done
>>
>> You need to quote $file here:
>> echo file: "$file"
>
>Generally a good idea to quote the variable, but in this case it won't
>help, the split on spaces has happened before the arguments get to the
>'echo'.
>
>I would suggest to the OP that they use a 'while' loop rather than 'for':
>
> find . -name '*txt' |
> while read n
> do
> echo "$n"
> done
> ./a b/tst.txt
> ./c/tst2.txt
>
>The 'read' gets the whole line, ignoring spaces.
The "read" builtin handles spaces as normal characters, but it can mishandle
other characters like '. '-print0' piped into 'xargs -0' is fairly
foolproof, but not available everywhere. Having find run a shell script via
exec should work everywhere, and handles any character the platform support in
a filename.
--
Boyd Stephen Smith Jr. ,= ,-_-. =.
bss@iguanasuicide.net ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-'
http://iguanasuicide.net/ \_/
01-08-2010, 08:47 AM
Jon Dowland
Handle paths with spaces
On Thu, Jan 07, 2010 at 08:35:56AM -0800, Bob McGowan wrote:
> Doesn't work - bash and the 'for' loop work on newline
> terminated strings and don't know how to handle the null
> terminator from -print0:
That's why I said
> > Look at the -print0 arg for find and the -0 argument for
> > xargs.
You need to use them both, *instead* of the for loop.
> I would suggest to the OP that they use a 'while' loop
> rather than 'for':
snip
> The 'read' gets the whole line, ignoring spaces.
Let's hope none of the files have newlines in their names.