zsh-users
 help / color / mirror / code / Atom feed
* Zsh noob: word-splitting headache
@ 2005-01-04 21:03 kynn
  2005-01-04 21:10 ` Clint Adams
  2005-01-04 21:30 ` Bart Schaefer
  0 siblings, 2 replies; 6+ messages in thread
From: kynn @ 2005-01-04 21:03 UTC (permalink / raw)
  To: zsh-users



I'm writing this script in which, among other things, I want to do
something for each line output by some command foo.  The problem is
that the lines output by foo contain whitespace (e.g. "bar baz
frobozz"), so a construct like this

  for i in `foo`
    do something with $i
  done

fails, because i holds individual words instead of whole lines.

I've tried every trick I can think of to prevent the intra-line
word splitting while still allowing the inter-line splitting, but
nothng has worked.  What's the right way to do this?

I looked at the FAQ at http://zsh.sunsite.dk/FAQ for an answer to this
question (as well as the Zsh Manual, the Zsh User Guide, and "From
Bash to Z-Shell", but no luck.

BTW, of all the difficulties I have programming zsh (or any shell for
that matter), a great many of them are in one way or another related
to word splitting.  Is there a *programming* FAQ on zsh word
splitting?

Thanks!

kj


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh noob: word-splitting headache
  2005-01-04 21:03 Zsh noob: word-splitting headache kynn
@ 2005-01-04 21:10 ` Clint Adams
  2005-01-04 21:35   ` kynn
  2005-01-06  2:36   ` Philippe Troin
  2005-01-04 21:30 ` Bart Schaefer
  1 sibling, 2 replies; 6+ messages in thread
From: Clint Adams @ 2005-01-04 21:10 UTC (permalink / raw)
  To: kynn; +Cc: zsh-users

>   for i in `foo`
>     do something with $i
>   done

  for i in ${(f)"$(foo)"}
    do something with $i
  done


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh noob: word-splitting headache
  2005-01-04 21:03 Zsh noob: word-splitting headache kynn
  2005-01-04 21:10 ` Clint Adams
@ 2005-01-04 21:30 ` Bart Schaefer
  2005-01-07 12:03   ` Stephane Chazelas
  1 sibling, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2005-01-04 21:30 UTC (permalink / raw)
  To: kynn; +Cc: zsh-users

On Tue, 4 Jan 2005 kynn@panix.com wrote:

>   for i in `foo`
>     do something with $i
>   done
> 
> fails, because i holds individual words instead of whole lines.

Use a different construct.

   foo | while read i; do something with $i; done

This works nicely in zsh because zsh executes the right-hand-side of 
pipelines in the current shell when it can.  It might not work as well in 
other shells, but other shells don't have Clint's suggested ${(f)...} 
expansion either.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh noob: word-splitting headache
  2005-01-04 21:10 ` Clint Adams
@ 2005-01-04 21:35   ` kynn
  2005-01-06  2:36   ` Philippe Troin
  1 sibling, 0 replies; 6+ messages in thread
From: kynn @ 2005-01-04 21:35 UTC (permalink / raw)
  To: zsh-users



   Date: Tue, 4 Jan 2005 16:10:25 -0500
   From: Clint Adams <clint@zsh.org>

   >   for i in `foo`
   >     do something with $i
   >   done

     for i in ${(f)"$(foo)"}
       do something with $i
     done

What a godsend!  Thanks!

kj


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh noob: word-splitting headache
  2005-01-04 21:10 ` Clint Adams
  2005-01-04 21:35   ` kynn
@ 2005-01-06  2:36   ` Philippe Troin
  1 sibling, 0 replies; 6+ messages in thread
From: Philippe Troin @ 2005-01-06  2:36 UTC (permalink / raw)
  To: Clint Adams; +Cc: kynn, zsh-users

Clint Adams <clint@zsh.org> writes:

> >   for i in `foo`
> >     do something with $i
> >   done
> 
>   for i in ${(f)"$(foo)"}
>     do something with $i
>   done

I tend to prefer making foo print NUL-separated records and use:

  for i in ${(ps:\0:)"$(foo)"}
    do something with $i
  done

  works with such foos as "find . -print0"

Now, I can handle ANY filename, including the ones containing
newlines.

Phil.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Zsh noob: word-splitting headache
  2005-01-04 21:30 ` Bart Schaefer
@ 2005-01-07 12:03   ` Stephane Chazelas
  0 siblings, 0 replies; 6+ messages in thread
From: Stephane Chazelas @ 2005-01-07 12:03 UTC (permalink / raw)
  To: zsh-users

On Tue, Jan 04, 2005 at 01:30:44PM -0800, Bart Schaefer wrote:
[...]
>    foo | while read i; do something with $i; done

foo | while IFS= read -r i; do something with "$i"; done

or leading and trailing blanks would be stripped, and backslash
would be treated specially.

Note that this means that "something" stdin is modified.

The quotes around "$i" are here in case there are empty lines.

Note that in

for i in ${(f)"$(foo)"}

or

IFS=$'\n'
for i in $(foo)

The empty lines are discarded.

To avoid that, you can do:

IFS=$'\n\n'
for i in $(foo)

But still, because of the (to my mind bogus) way command
substitution works in Bourne like shells, the empty lines at the
end of foo output will still be discarded. To prevent that, you
can do:

IFS=$'\n\n'
for i in ${$(foo; echo .)[1,-2]}

$ printf '<%s>\n' ${$(echo 'a b\n\n'; echo .)[1,-2]}
<a b>
<>
<>

-- 
Stéphane


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-01-07 12:02 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-04 21:03 Zsh noob: word-splitting headache kynn
2005-01-04 21:10 ` Clint Adams
2005-01-04 21:35   ` kynn
2005-01-06  2:36   ` Philippe Troin
2005-01-04 21:30 ` Bart Schaefer
2005-01-07 12:03   ` Stephane Chazelas

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).