* somehow offtopic: looping filenames @ 2012-02-20 18:16 meino.cramer 2012-02-20 18:38 ` Frank Terbeck 2012-02-20 19:05 ` Bart Schaefer 0 siblings, 2 replies; 6+ messages in thread From: meino.cramer @ 2012-02-20 18:16 UTC (permalink / raw) To: zsh-users Hi, how can I do this in a most compact, direct, and zsh like way: I habe a loop like this: for fn * do flac $fn done Unfortunately, some file have 'illegal' filenames like 20120220-_-19db.wav or 20120220 sensor10 up.wav which parts flac sees as unknown commmand options or as two file and the loop fails. How do I have to modifiy the loop to make it immune against such filenames ? Thank you very much in advance for any help! Best regards mcc ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: somehow offtopic: looping filenames 2012-02-20 18:16 somehow offtopic: looping filenames meino.cramer @ 2012-02-20 18:38 ` Frank Terbeck 2012-02-20 19:05 ` Bart Schaefer 1 sibling, 0 replies; 6+ messages in thread From: Frank Terbeck @ 2012-02-20 18:38 UTC (permalink / raw) To: zsh-users meino.cramer@gmx.de wrote: > I habe a loop like this: > > for fn * > do > flac $fn > done > > Unfortunately, some file have 'illegal' filenames like > > 20120220-_-19db.wav > or > 20120220 sensor10 up.wav > > > which parts flac sees as unknown commmand options or as > two file and the loop fails. So, you're setting `sh_word_split'? Or are you using another shell? This should work in every shell: for i in ./*; do flac "$i" done The ./ makes sure the file name cannot start in a dash, which many applications would otherwise take as an option name. The "$i" makes sure the shell sees the variable contents as one word. Zsh does that with unquoted parameters by default. You'll have to set the `sh_word_split' option to get a more bourne-shell-like behaviour. Regards, Frank -- In protocol design, perfection has been reached not when there is nothing left to add, but when there is nothing left to take away. -- RFC 1925 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: somehow offtopic: looping filenames 2012-02-20 18:16 somehow offtopic: looping filenames meino.cramer 2012-02-20 18:38 ` Frank Terbeck @ 2012-02-20 19:05 ` Bart Schaefer 2012-02-21 12:35 ` Stephen Blott 1 sibling, 1 reply; 6+ messages in thread From: Bart Schaefer @ 2012-02-20 19:05 UTC (permalink / raw) To: zsh-users On Feb 20, 7:16pm, meino.cramer@gmx.de wrote: } } I habe a loop like this: } } for fn * } do } flac $fn } done } } Unfortunately, some file have 'illegal' filenames } which parts flac sees as unknown commmand options or as } two file and the loop fails. Try this: for fn * do flac $fn:a done The :a modifier expands $fn into a full path including removing any mentions of "./" and "../". Think of it as a clean "$PWD/$fn". If you don't have a recent-enough zsh for :a to be supported or it is for some reason important to avoid the full path, try flac ${${fn:h}-.}/${fn:t} If that's still confusing it because e.g. you have SH_WORD_SPLIT turned on, wrap the expression in double quotes. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: somehow offtopic: looping filenames 2012-02-20 19:05 ` Bart Schaefer @ 2012-02-21 12:35 ` Stephen Blott 2012-02-21 13:35 ` Frank Terbeck 0 siblings, 1 reply; 6+ messages in thread From: Stephen Blott @ 2012-02-21 12:35 UTC (permalink / raw) To: zsh-users On Mon, Feb 20, 2012 at 11:05:30AM -0800, Bart Schaefer wrote: > On Feb 20, 7:16pm, meino.cramer@gmx.de wrote: > } > } I habe a loop like this: > } > } for fn * > } do > } flac $fn > } done > } > } Unfortunately, some file have 'illegal' filenames > } which parts flac sees as unknown commmand options or as > } two file and the loop fails. > > Try this: > > for fn * > do > flac $fn:a > done > > The :a modifier expands $fn into a full path including removing any > mentions of "./" and "../". Think of it as a clean "$PWD/$fn". > > If you don't have a recent-enough zsh for :a to be supported or it is > for some reason important to avoid the full path, try > > flac ${${fn:h}-.}/${fn:t} > > If that's still confusing it because e.g. you have SH_WORD_SPLIT turned > on, wrap the expression in double quotes. > ---end quoted text--- Or: ls | tr '\n' '\0' | xargs -0 -n 1 flac -- If you're using Gnu xargs then you might need the -r/--no-run-if-empty flag too. Steve ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: somehow offtopic: looping filenames 2012-02-21 12:35 ` Stephen Blott @ 2012-02-21 13:35 ` Frank Terbeck 2012-02-22 23:41 ` Mark van Dijk 0 siblings, 1 reply; 6+ messages in thread From: Frank Terbeck @ 2012-02-21 13:35 UTC (permalink / raw) To: zsh-users Stephen Blott wrote: [...] > ls | tr '\n' '\0' | xargs -0 -n 1 flac -- This is a pet peeve of mine, so I need to chime in... Using ls for generating file lists is always wrong. And always, there is a more robust way of dealing with the problem at hand using either shell globing or `find(1)'. (I used to have two "almost"s in that paragraph, but leaving them in would really overstate the relevance of possible situations¹.) There is nothing about this, that would improve the behaviour of a simple for loop like for i in *; flac -- $i (That's `short_loops' syntax, which is on by default in zsh. And it relies on `sh_word_split' being unset, which is also the default behaviour in zsh.) Worse, it's *less* robust, because it's treating newline characters specially, although they are perfectly legal characters in a file name (albeit not very common ones). Also, if the user has an alias in place, like say, alias ls='ls -F' ...that is not going to work either, because that will cause ls to append a / to directory names, a * to executable files and so on. I know there are HOWTOs and tutorials online, that advocate constructs like that. And even worse ones, like "for i in `ls`; do...". But that doesn't make them good examples of shell programming. I don't mean to offend with this reply. And I hope that my point is making sense to you. I've written about this in the past² (but it's in German) and so has the guy who maintains the FAQ for #bash (the IRC channel for GNU bash on freenode)³. Refer that that for more details on parsing the output from `ls'. Regards, Frank ¹ There was one time, when someone asked me: Okay so "for i in `ls`" is bad, but what about when I want the generated list to be sorted by some criteria (like by modification time instead of the usual alphabetic order). And that's indeed not that easy with POSIX shell. In zsh, however, there are glob qualifiers like (O.) and (o.) (where`.' is a character that specifies a property to sort by), which allow the user to sort the result of a glob to his/her requirements. So that point is moot as well, if we're talking about zsh. ² <http://bewatermyfriend.org/posts/2007/02-08.12-18-45-rants.html> ³ <http://mywiki.wooledge.org/ParsingLs> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: somehow offtopic: looping filenames 2012-02-21 13:35 ` Frank Terbeck @ 2012-02-22 23:41 ` Mark van Dijk 0 siblings, 0 replies; 6+ messages in thread From: Mark van Dijk @ 2012-02-22 23:41 UTC (permalink / raw) To: zsh-users Hi, > There is nothing about this, that would improve the behaviour of a > simple for loop like > > for i in *; flac -- $i > > (That's `short_loops' syntax, which is on by default in zsh. And it > relies on `sh_word_split' being unset, which is also the default > behaviour in zsh.) I agree to this. Also it's nice to pass a variable without being required to always specify it as ${foobar[@]}. Even better: to remind myself of the fact that a for loop often deals with arrays I became used to the following syntax: for i (*) echo $i and for i ($foobar) { command1; command 2 || print "command 2 failed!" } and if [[ -n $foo ]] { bar } else { baz } These are arbitrary examples of course; my point is that this syntax makes scripts more readable to me than the agonising if foo then bar else baz fi Especially with vim that highlights the opposite char ({) when you move to the original char (}). > Worse, it's *less* robust, because it's treating newline characters > specially, although they are perfectly legal characters in a file name > (albeit not very common ones). Also, if the user has an alias in > place, like say, > > alias ls='ls -F' > > ...that is not going to work either, because that will cause ls to > append a / to directory names, a * to executable files and so on. I remember trying to use aliases in a script. I don't think this works, I changed them to functions at least. But yes I do agree on this, here it even became a sport to minimise the use of external commands as much as possible. With zsh these tasks are often trivial. I suppose we all love examples that show zsh's power and what I found great is that even sed and awk can easily be replaced: cat $foobar | sed 's,Alice,Bob,g') versus ${foobar/Alice/Bob} (yes, bash can do this, too) cat /proc/sys/kernel/version | awk '{print $2}' versus ${$(</proc/sys/kernel/version)[(w)2]}. > I know there are HOWTOs and tutorials online, that advocate constructs > like that. And even worse ones, like "for i in `ls`; do...". But that > doesn't make them good examples of shell programming. Awfully written shell scripts have this much too often. > I don't mean to offend with this reply. And I hope that my point is > making sense to you. I've written about this in the past² (but it's in > German) and so has the guy who maintains the FAQ for #bash (the IRC > channel for GNU bash on freenode)³. Refer that that for more details > on parsing the output from `ls'. Additionally - it's a bit odd to prefer anything else above zsh's own powerful globbing abilities. I have used 'ls -dl /proc/**/*keyword*(.)' so often. I've often wondered if there is a Linux distribution using zsh as its default shell for users and distribution specific stuff like init scripts. I found your email nice to read, Frank. Ciao, -Mark. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-02-22 23:51 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-02-20 18:16 somehow offtopic: looping filenames meino.cramer 2012-02-20 18:38 ` Frank Terbeck 2012-02-20 19:05 ` Bart Schaefer 2012-02-21 12:35 ` Stephen Blott 2012-02-21 13:35 ` Frank Terbeck 2012-02-22 23:41 ` Mark van Dijk
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).