FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Debian > Debian User

 
 
LinkBack Thread Tools
 
Old 01-07-2010, 09:08 AM
Foss User
 
Default Handle paths with spaces

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?


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
 
Old 01-07-2010, 09:18 AM
Javier Barroso
 
Default 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
 
Old 01-07-2010, 09:19 AM
Alex Samad
 
Default 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.
 
Old 01-07-2010, 09:37 AM
Jon Dowland
 
Default 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
 
Old 01-07-2010, 03:35 PM
Bob McGowan
 
Default 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
 
Old 01-08-2010, 01:00 AM
"Boyd Stephen Smith Jr."
 
Default 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]

>do
> echo file: $file
>done

Try this:
find -name "*.txt" -exec /bin/sh -c 'echo file: $1' ignored {} ;

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/ \_/
 
Old 01-08-2010, 01:07 AM
"Boyd Stephen Smith Jr."
 
Default 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/ \_/
 
Old 01-08-2010, 08:47 AM
Jon Dowland
 
Default 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.
 

Thread Tools




All times are GMT. The time now is 09:01 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org