* 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).