From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19863 invoked by alias); 19 Jan 2015 16:27:43 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 19750 Received: (qmail 9401 invoked from network); 19 Jan 2015 16:27:39 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,T_FSL_HELO_BARE_IP_2 autolearn=ham version=3.3.2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1421684210; bh=Arkq9OUlmHdU/gSFxV+Vp/ZZjPXKtwRdX3O6opn4dEA=; h=From:To:In-Reply-To:References:Subject:Date; b=s0lRJXxu3K3+FyYXkdrlDSe1aw9TqL5n7v+IYIbKByrqdD7VPObkKZqutAiNGuof5 WYaVaYbDyvmFyoIIB43FAkYcLv56V+NTYmi6iWFv/HJMZuw/kNjC3IqXkoTViNeWy1 nn+fS/SzR1d4GCW+Z3c31CVC7LdGqIyhKsaFZKDw= From: ZyX To: Eric Cook , "zsh-users@zsh.org" In-Reply-To: <1136081421683325@web6h.yandex.ru> References: <54BC1B8E.5080806@gmx.com> <1102431421682670@web6h.yandex.ru> <1115311421682921@web6h.yandex.ru> <1136081421683325@web6h.yandex.ru> Subject: Re: Equivalent of set -- *(DN) in sh MIME-Version: 1.0 Message-Id: <1178831421684209@web6h.yandex.ru> X-Mailer: Yamail [ http://yandex.ru ] 5.0 Date: Mon, 19 Jan 2015 19:16:49 +0300 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=utf-8 19.01.2015, 19:02, "ZyX" : > 19.01.2015, 18:55, "ZyX" : >>  19.01.2015, 18:51, "ZyX" : >>>   18.01.2015, 23:53, "Eric Cook" : >>>>    On 01/18/2015 01:28 PM, Nikolai Weibull wrote: >>>>>     Hi! >>>>> >>>>>     Is there any way to get the equivalent of Zsh’s >>>>> >>>>>     set -- *(DN) >>>>> >>>>>     in sh?  Most important here would be NULL_GLOB, as, by default, sh >>>>>     simply leaves the * if there are no files to match. >>>>> >>>>>     Thanks! >>>>    match() { >>>>      test "$#" -gt 2 && return >>>>      test -e "$1"    && return >>>>      return 1 >>>>    } >>>> >>>>    set -- >>>>    for pat in '.[^.]*' '*'; do # *(DN) ignores . and .. >>>   `..foo` is a valid name, but it is being excluded. You need to add `'.??*'` to the list of patterns. >>  No, this may make duplicates. Then `'..?*'`. > > And you must replace `[^.]` with `[!.]`. mksh does not support `[^]` and treats this as `[\^.]`, but other shells I have (dash, ksh, zsh (in sh emulation mode), bash, busybox ash) are fine with both `[!.]` and `[^.]`. >>>>      if match $pat; then >>>>        set -- "$@" $pat >>>>      fi >>>>    done >>>>    unset pat >>>> >>>>    test "$#" -gt 0 && printf '%s\n' "$@" Also note that if you need *full* equivalent of *(DN) you need to do something with ordering. I have checked all the shells with for sh in dash ksh mksh zsh bash bb ; do $sh set--sDN.sh > set--sDN.$sh.log ; done with emulate -L sh &>/dev/null match() { test "$#" -gt 2 && return test -e "$1" && return return 1 } set -- for pat in '.[!.]*' '..?*' '*'; do # *(DN) ignores . and .. if match $pat; then set -- "$@" $pat fi done unset pat test "$#" -gt 0 && printf '>>%s<<\n' "$@" in set--sDN.sh file and have the following md5sums: % md5sum set--sDN.*.log | sort 4601e6d9c845fe88e5166db3be04cc75 set--sDN.bash.log 4601e6d9c845fe88e5166db3be04cc75 set--sDN.ksh.log 4601e6d9c845fe88e5166db3be04cc75 set--sDN.zsh.log ac2c245cdac664121a348c6b05ea2f44 set--sDN.bb.log ac2c245cdac664121a348c6b05ea2f44 set--sDN.dash.log ac2c245cdac664121a348c6b05ea2f44 set--sDN.mksh.log : two variants of ordering: bash/ksh/zsh: >>.abc<< >>.b<< >>.^foo<< >>..foo<< >> << >>1<< >>17<< >>2<< >>append-remove.bash<< >>getnumbers.bash<< >>grepdir<< >>nroff<< >>parinput.bash<< >>qwerty<< >>rl.sh<< >>script_path.bash<< >>set--sDN.bash.log<< >>set--sDN.bb.log<< >>set--sDN.dash.log<< >>set--sDN.ksh.log<< >>set--sDN.mksh.log<< >>set--sDN.sh<< >>set--sDN.zsh.log<< >>tes.bash<< >>test<< >>test2.bash<< >>test3.bash<< >>test.bash<< >>testdir<< >>test-rename.sh<< >>test-so-2914220.bash<< >>t.tar<< >>ttttt.tar.bz2<< >>ttttt.tar.gz<< bb/dash/mksh: >>.^foo<< >>.abc<< >>.b<< >>..foo<< >> << >>1<< >>17<< >>2<< >>append-remove.bash<< >>getnumbers.bash<< >>grepdir<< >>nroff<< >>parinput.bash<< >>qwerty<< >>rl.sh<< >>script_path.bash<< >>set--sDN.bash.log<< >>set--sDN.bb.log<< >>set--sDN.dash.log<< >>set--sDN.ksh.log<< >>set--sDN.mksh.log<< >>set--sDN.sh<< >>set--sDN.zsh.log<< >>t.tar<< >>tes.bash<< >>test<< >>test-rename.sh<< >>test-so-2914220.bash<< >>test.bash<< >>test2.bash<< >>test3.bash<< >>testdir<< >>ttttt.tar.bz2<< >>ttttt.tar.gz<< (note position of t.tar). I have verified that all tests emit essentially the same result by using `for f in set--sDN.*.log ; do cat $f | sort | md5sum ; done | uniq`. But both orderings are different from the zsh one: % zsh -f -c 'for f in *(DN); do echo ">>$f<<" ; done' >> << >>1<< >>17<< >>2<< >>.abc<< >>append-remove.bash<< >>.b<< >>.^foo<< >>..foo<< >>getnumbers.bash<< >>grepdir<< >>nroff<< >>parinput.bash<< >>qwerty<< >>rl.sh<< >>script_path.bash<< >>set--sDN.bash.log<< >>set--sDN.bb.log<< >>set--sDN.dash.log<< >>set--sDN.ksh.log<< >>set--sDN.mksh.log<< >>set--sDN.sh<< >>set--sDN.zsh.log<< >>tes.bash<< >>test<< >>test2.bash<< >>test3.bash<< >>test.bash<< >>testdir<< >>test-rename.sh<< >>test-so-2914220.bash<< >>t.tar<< >>ttttt.tar.bz2<< >>ttttt.tar.gz<< (note: I have filename with newline, this is why I added `>><<`.)