* Use glob patterns while reading a file @ 2018-11-08 22:53 ` Dominik Ritter 2018-11-09 9:35 ` Peter Stephenson 0 siblings, 1 reply; 7+ messages in thread From: Dominik Ritter @ 2018-11-08 22:53 UTC (permalink / raw) To: zsh-users [-- Attachment #1: Type: text/plain, Size: 523 bytes --] Hi all! I want to use read one of two files, regardless if it exists or not. My first approach is to use the alternative glob syntax, but with no luck: $(< ./(a|b)(N)) Without the subshell, the glob is expanded first, thus it works: < ./(a|b)(N) Is it possible to get this to work in conjunction with a subshell? The usual workarounds are to expand the glob first, and iterate over the resulting files, test for existance and finally read the contents. This seems quite cumbersome to me. Thanks for your help, Dominik ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Use glob patterns while reading a file 2018-11-08 22:53 ` Use glob patterns while reading a file Dominik Ritter @ 2018-11-09 9:35 ` Peter Stephenson 2018-11-09 14:37 ` Dominik Ritter 2018-11-10 1:21 ` Daniel Shahaf 0 siblings, 2 replies; 7+ messages in thread From: Peter Stephenson @ 2018-11-09 9:35 UTC (permalink / raw) To: zsh-users On Thu, 2018-11-08 at 23:53 +0100, Dominik Ritter wrote: > I want to use read one of two files, regardless if it exists or not. My > first approach is to use the alternative glob syntax, but with no luck: > $(< ./(a|b)(N)) That's a special syntax, expecting a single file so that it doesn't try to do globbing. You can get it to work with $(cat <./(a|b)(N)) pws ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Use glob patterns while reading a file 2018-11-09 9:35 ` Peter Stephenson @ 2018-11-09 14:37 ` Dominik Ritter 2018-11-09 16:20 ` Peter Stephenson 2018-11-10 1:21 ` Daniel Shahaf 1 sibling, 1 reply; 7+ messages in thread From: Dominik Ritter @ 2018-11-09 14:37 UTC (permalink / raw) To: p.stephenson; +Cc: zsh-users [-- Attachment #1: Type: text/plain, Size: 1464 bytes --] I was hoping for a solution without externals. The cat version seems to be slower than the other one, and I the null glob seems not to work, if neither of the files was found.. Testing 10000 iterations of cat-glob ( repeat $ITERATIONS; do; echo $(cat < ./(a|b)(N) 2>/dev/null ) > /dev/null 2) 5,75s user 2,61s system 107% cpu 7,741 total Testing 10000 iterations of resolve-first glob ( repeat $ITERATIONS; do; local -a files; files=(./(a|b)(N)) ; for file in ; ) 0,11s user 0,16s system 98% cpu 0,276 total With "b" being a simple text file. Test-Script: #!/bin/zsh ITERATIONS=10000 echo "Testing $ITERATIONS iterations of cat-glob" time (repeat $ITERATIONS; do; echo $(cat < ./(a|b)(N) 2>/dev/null ) >/dev/null 2>&1 done;) echo "Testing $ITERATIONS iterations of resolve-first glob" time (repeat $ITERATIONS; do; local -a files files=( ./(a|b)(N) ) for file in $files; do; echo $(< ${file} ) >/dev/null done done;) Am Fr., 9. Nov. 2018 um 10:36 Uhr schrieb Peter Stephenson < p.stephenson@samsung.com>: > On Thu, 2018-11-08 at 23:53 +0100, Dominik Ritter wrote: > > I want to use read one of two files, regardless if it exists or not. My > > first approach is to use the alternative glob syntax, but with no luck: > > $(< ./(a|b)(N)) > > That's a special syntax, expecting a single file so that it doesn't try > to do globbing. > > You can get it to work with > > $(cat <./(a|b)(N)) > > pws > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Use glob patterns while reading a file 2018-11-09 14:37 ` Dominik Ritter @ 2018-11-09 16:20 ` Peter Stephenson 0 siblings, 0 replies; 7+ messages in thread From: Peter Stephenson @ 2018-11-09 16:20 UTC (permalink / raw) To: Zsh Users' List On Fri, 2018-11-09 at 15:37 +0100, Dominik Ritter wrote: > I was hoping for a solution without externals. The cat version seems > to be slower than the other one, and I the null glob seems not to > work, if neither of the files was found.. There are various ways of outputting files from within the shell. You can do something like zmodload zsh/mapfile ... $(files=(./(a|b)(N)); print -nr "$mapfile[$files[1]]") pws ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Use glob patterns while reading a file 2018-11-09 9:35 ` Peter Stephenson 2018-11-09 14:37 ` Dominik Ritter @ 2018-11-10 1:21 ` Daniel Shahaf 2018-11-10 2:07 ` Bart Schaefer 1 sibling, 1 reply; 7+ messages in thread From: Daniel Shahaf @ 2018-11-10 1:21 UTC (permalink / raw) To: zsh-users Peter Stephenson wrote on Fri, 09 Nov 2018 09:35 +0000: > On Thu, 2018-11-08 at 23:53 +0100, Dominik Ritter wrote: > > I want to use read one of two files, regardless if it exists or not. My > > first approach is to use the alternative glob syntax, but with no luck: > > $(< ./(a|b)(N)) > > That's a special syntax, expecting a single file so that it doesn't try > to do globbing. I think this violates the principle of least surprise. Grammars should be composable and shouldn't have special cases. The forms «foo» and «print -r -- "$(<foo)"» should always be equivalent (assuming 'foo' outputs a trailing newline). Similarly, «<foo» and «<foo $READNULLCMD» are usually equivalent, but «$(<*)» and «$(<* $READNULLCMD)» are not. (I know that $(<foo) is optimised, but the whole point of optimisations is that they don't change the semantics.) By default, «*» after «<» is a glob. There is no reason for a user to expect «$(<*)» to be different: neither command substitution nor input redirection implies 'noglob' or NO_MULTIOS in any other situation. Frankly, I'm tempted to treat it as a bug — but before I jump to conclusions, was this behaviour intentionally implemented this way? > The manual says: . The substitution `tt($LPAR()cat) var(foo)tt(RPAR())' may be replaced by the equivalent but faster `tt($LPAR()<)var(foo)tt(RPAR())'. . which is correct only when var(foo) does not involve globbing. I don't want to open the user manual v. reference manual can of worms again, but I think there is room for improvement here. > You can get it to work with > > $(cat <./(a|b)(N)) Cheers, Daniel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Use glob patterns while reading a file 2018-11-10 1:21 ` Daniel Shahaf @ 2018-11-10 2:07 ` Bart Schaefer 2018-11-10 2:12 ` Bart Schaefer 0 siblings, 1 reply; 7+ messages in thread From: Bart Schaefer @ 2018-11-10 2:07 UTC (permalink / raw) To: Daniel Shahaf; +Cc: Zsh Users On Fri, Nov 9, 2018 at 5:22 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote: > > > > $(< ./(a|b)(N)) > > > > That's a special syntax, expecting a single file so that it doesn't try > > to do globbing. > > I think this violates the principle of least surprise. Grammars should be > composable and shouldn't have special cases. Although I can't argue with this from a philosophical standpoint, I find it astonishing to pretend that zsh ignores that philosophy only in this particular case. > The forms «foo» and > «print -r -- "$(<foo)"» should always be equivalent (assuming 'foo' outputs > a trailing newline). I don't follow that at all. «foo» is a shell word. «print -r -- "$(<foo)"» is the contents of a file identified by the word «foo». In what context are those equivalent? > Similarly, «<foo» and «<foo $READNULLCMD» are usually > equivalent, but «$(<*)» and «$(<* $READNULLCMD)» are not. The distinction here is that $(...) is a substitution, not a subshell. It's more like a quoting mechanism (i.e. `foo`). $(<foo) is NOT an "optimization" of $({<foo}) (which does work exactly the way you think it would, globbing-wise), and the "<" in that position in the substitution is not a redirection operator, even though it looks like one for mnemonic reasons. $(<...) is an entirely different thing, just like $((...)) is a different thing, even though «$(» and «<» do not have to be composed without whitespace to form a token. > was this behaviour intentionally implemented this way? Yes. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Use glob patterns while reading a file 2018-11-10 2:07 ` Bart Schaefer @ 2018-11-10 2:12 ` Bart Schaefer 0 siblings, 0 replies; 7+ messages in thread From: Bart Schaefer @ 2018-11-10 2:12 UTC (permalink / raw) To: Daniel Shahaf; +Cc: Zsh Users Just to be a little more accurate ... On Fri, Nov 9, 2018 at 6:07 PM Bart Schaefer <schaefer@brasslantern.com> wrote: > > $(<...) is an entirely different thing I should say $(<WORD) for a single WORD is a thing, and thus is distinct from $(<WORD WORD...) where "<" becomes a redirection again. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-11-10 2:13 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <CGME20181108225555epcas2p274de218aef35e46f189ebbfbd9d1892f@epcas2p2.samsung.com> 2018-11-08 22:53 ` Use glob patterns while reading a file Dominik Ritter 2018-11-09 9:35 ` Peter Stephenson 2018-11-09 14:37 ` Dominik Ritter 2018-11-09 16:20 ` Peter Stephenson 2018-11-10 1:21 ` Daniel Shahaf 2018-11-10 2:07 ` Bart Schaefer 2018-11-10 2:12 ` Bart Schaefer
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).