* Fun zsh trick for today @ 2000-06-10 22:50 Bart Schaefer 0 siblings, 0 replies; 12+ messages in thread From: Bart Schaefer @ 2000-06-10 22:50 UTC (permalink / raw) To: zsh-users Some of you are probably familiar with Perl's "grep" function; given a regular expression and an array, it returns all the elements of the array that match the expression. A common Perl idiom is open(FILE, "<somefile"); @result = grep(/pat/, <FILE>); Where <FILE> slurps somefile into memory as an array of lines. Did you know that zsh can do that, too? If you load the mapfile module: zmodload -i zsh/mapfile Then you can write Perl's open(FILE, "<somefile") as $mapfile[somefile] And you can write <FILE> as ${(f)mapfile[somefile]} with the caveat that blank lines are stripped out. (If you're using zsh 3.0.x or can't load the mapfile module, you can do the same thing with "${(f)$(<somefile)}". It's just not quite as efficient, and you have to remember to use the double quotes around it.) You can write grep(/pat/, array) as ${(M)array:#*pat*} with the caveat that pat is a glob pattern -- but with extendedglob set, zsh's glob patterns are full regular expressions, although with a non-sed- like syntax because of the different special meaning of '*'. So finally, @result = grep(/pat/, <FILE>) is result=(${(M)${(f)mapfile[somefile]}:#*pat*}) Try, for example, ${(M)#${(f)mapfile[ChangeLog]}:#*Sven*} to see that there are 1023 mentions of Sven's name in zsh's ChangeLog file. (I only managed 265 "Bart"s; in fact, there are only 475 lines with the word "zsh"!) -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.brasslantern.com Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net ^ permalink raw reply [flat|nested] 12+ messages in thread
[parent not found: <no.id>]
* Re: Fun zsh trick for today [not found] <no.id> @ 2000-06-14 13:43 ` Matthias Kopfermann 2000-06-14 13:57 ` Clint Adams 2000-06-14 15:33 ` Matthias Kopfermann 2000-06-14 16:31 ` Matthias Kopfermann 2 siblings, 1 reply; 12+ messages in thread From: Matthias Kopfermann @ 2000-06-14 13:43 UTC (permalink / raw) To: Bart Schaefer; +Cc: zsh-users On Sat, Jun 10, 2000 at 10:50:51PM +0000, Bart Schaefer wrote: >[ ... amazing information deleted ] i think, this would be a great feature of the mailinglist, if bart or sven or some other guru would give such nice tricks once a week or something. it makes happy user, at least it made me happy :) Matthias ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today 2000-06-14 13:43 ` Matthias Kopfermann @ 2000-06-14 13:57 ` Clint Adams 2000-06-14 14:09 ` Ollivier Robert 2000-06-14 14:15 ` Peter Stephenson 0 siblings, 2 replies; 12+ messages in thread From: Clint Adams @ 2000-06-14 13:57 UTC (permalink / raw) To: Matthias Kopfermann; +Cc: Bart Schaefer, zsh-users > i think, this would be a great feature of the mailinglist, if > bart or sven or some other guru would give such nice tricks once > a week or something. > it makes happy user, at least it made me happy :) I'm no Bart-guru, but here's an application of his trick that I find useful for the new completion system: zmodload -i zsh/mapfile hosts=(${(@)${(@)${(M)${(f)mapfile[$HOME/.ssh/known_hosts]}:#[^0-9]*}%%\ *}%%,*}) zstyle ':completion:*:hosts' hosts $hosts ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today 2000-06-14 13:57 ` Clint Adams @ 2000-06-14 14:09 ` Ollivier Robert 2000-06-14 15:02 ` Fletch 2000-06-14 14:15 ` Peter Stephenson 1 sibling, 1 reply; 12+ messages in thread From: Ollivier Robert @ 2000-06-14 14:09 UTC (permalink / raw) To: zsh-users According to Clint Adams: > zmodload -i zsh/mapfile > hosts=(${(@)${(@)${(M)${(f)mapfile[$HOME/.ssh/known_hosts]}:#[^0-9]*}%%\ *}%%,*}) <humour> I'm beginning to see zsh turning up into perl-sh... :-) </humour> -- Ollivier ROBERT -=- Eurocontrol EEC/TEC -=- roberto@eurocontrol.fr The Postman hits! The Postman hits! You have new mail. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today 2000-06-14 14:09 ` Ollivier Robert @ 2000-06-14 15:02 ` Fletch 0 siblings, 0 replies; 12+ messages in thread From: Fletch @ 2000-06-14 15:02 UTC (permalink / raw) To: Ollivier Robert; +Cc: zsh-users >>>>> "Ollivier" == Ollivier Robert <roberto@eurocontrol.fr> writes: Ollivier> According to Clint Adams: >> zmodload -i zsh/mapfile >> hosts=(${(@)${(@)${(M)${(f)mapfile[$HOME/.ssh/known_hosts]}:#[^0-9]*}%%\ >> *}%%,*}) Ollivier> <humour> I'm beginning to see zsh turning up into Ollivier> perl-sh... :-) </humour> Well, I've got a patch off of 3.1.6 that embeds a perl interpreter as a loadable module and let's you call perl subroutines as zsh functions . . . :) I really need to update it work with 3.1.9, though. -- Fletch | "If you find my answers frightening, __`'/| fletch@phydeaux.org | Vincent, you should cease askin' \ o.O' 678 443-6239(w) | scary questions." -- Jules =(___)= | U ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today 2000-06-14 13:57 ` Clint Adams 2000-06-14 14:09 ` Ollivier Robert @ 2000-06-14 14:15 ` Peter Stephenson 2000-06-14 14:21 ` Peter Stephenson ` (2 more replies) 1 sibling, 3 replies; 12+ messages in thread From: Peter Stephenson @ 2000-06-14 14:15 UTC (permalink / raw) To: Zsh users list > I'm no Bart-guru, but here's an application of his trick that I find useful > for the new completion system: > > zmodload -i zsh/mapfile > hosts=(${(@)${(@)${(M)${(f)mapfile[$HOME/.ssh/known_hosts]}:#[^0-9]*}%%\ *}%% > ,*}) > zstyle ':completion:*:hosts' hosts $hosts In something like this there's really no gain over doing it using more ordinary zsh methods, i.e. with $(<...), which doesn't require a module. Plus you don't need all those (@)'s once parameter substitution already has arrays, which (f) provides. The only trick here is using double quotes to get whole lines for splitting. I think the following should work in 3.0.8 (can't quite remember if the trick of putting double quotes in the middle made its way back --- if not, put quotes around the lot and put (@)'s at the front of all the parameter substitutions). hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[^0-9]*}%%\ *}%%,* }) or hosts=("${(@)${(@)${(@M)${(@f)"$(<$HOME/.ssh/known_hosts)"}:#[^0-9]*}%%\ *}%%,* }") -- Peter Stephenson <pws@cambridgesiliconradio.com> Cambridge Silicon Radio, Unit 300, Science Park, Milton Road, Cambridge, CB4 0XL, UK Tel: +44 (0)1223 392070 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today 2000-06-14 14:15 ` Peter Stephenson @ 2000-06-14 14:21 ` Peter Stephenson 2000-06-14 14:27 ` Clint Adams 2000-06-14 14:37 ` Bart Schaefer 2 siblings, 0 replies; 12+ messages in thread From: Peter Stephenson @ 2000-06-14 14:21 UTC (permalink / raw) To: Zsh users list I wrote: > or > > hosts=("${(@)${(@)${(@M)${(@f)"$(<$HOME/.ssh/known_hosts)"}:#[^0-9]*}%%\ *}%% > ,* > }") ^ ^ erk, sorry, remove the double quotes in the middle in this case. -- Peter Stephenson <pws@cambridgesiliconradio.com> Cambridge Silicon Radio, Unit 300, Science Park, Milton Road, Cambridge, CB4 0XL, UK Tel: +44 (0)1223 392070 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today 2000-06-14 14:15 ` Peter Stephenson 2000-06-14 14:21 ` Peter Stephenson @ 2000-06-14 14:27 ` Clint Adams 2000-06-14 14:37 ` Bart Schaefer 2 siblings, 0 replies; 12+ messages in thread From: Clint Adams @ 2000-06-14 14:27 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh users list > hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[^0-9]*}%%\ *}%%,*}) This has the opposite effect as desired (i.e., it returns an array containing only those entries beginning with digits). This does what I want (except for omitting things like 3stop.com): hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[0-9]*}%%\ *}%%,*}) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today 2000-06-14 14:15 ` Peter Stephenson 2000-06-14 14:21 ` Peter Stephenson 2000-06-14 14:27 ` Clint Adams @ 2000-06-14 14:37 ` Bart Schaefer 2 siblings, 0 replies; 12+ messages in thread From: Bart Schaefer @ 2000-06-14 14:37 UTC (permalink / raw) To: Peter Stephenson, Zsh users list On Jun 14, 3:15pm, Peter Stephenson wrote: } Subject: Re: Fun zsh trick for today } } Plus you don't need all those (@)'s once parameter substitution already has } arrays, which (f) provides. The only trick here is using double quotes to } get whole lines for splitting. I think the following should work in 3.0.8 } (can't quite remember if the trick of putting double quotes in the middle } made its way back The quotes in the middle is in 3.0.7, as part of the "minimal forwards compatibility" effort. There is a small bug with them in both versions, though; you can't take the length of the quoted part: zagzig[57] echo ${#"${(f)$(<file)}"} zsh: bad substitution zagzig[60] echo ${#${"${(f)$(<ChangeLog)}"}} 8017 It works with ${=...} and ${~...}, but not with ${#...}. -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.brasslantern.com Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today [not found] <no.id> 2000-06-14 13:43 ` Matthias Kopfermann @ 2000-06-14 15:33 ` Matthias Kopfermann 2000-06-14 15:52 ` Peter Stephenson 2000-06-14 16:31 ` Matthias Kopfermann 2 siblings, 1 reply; 12+ messages in thread From: Matthias Kopfermann @ 2000-06-14 15:33 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh users list > > hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[^0-9]*}%%\ *}%%,* > }) hu %) Could someone explain these hieroglyphs for a simple soul like me? %%) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today 2000-06-14 15:33 ` Matthias Kopfermann @ 2000-06-14 15:52 ` Peter Stephenson 0 siblings, 0 replies; 12+ messages in thread From: Peter Stephenson @ 2000-06-14 15:52 UTC (permalink / raw) To: Zsh users list > > > > hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[^0-9]*}%%\ *}%%,* > > }) > hu %) Could someone explain these hieroglyphs for a simple soul > like me? %%) that's why this is deferred till (the unwritten) chapter 5 of the user guide, instead of the chapter on basic syntax... $(<$HOME/.ssh/known_hosts) is a standard substitution: it simply takes the file and sticks it onto the command line at that point. "$(<$HOME/.ssh/known_hosts)" Now it's quoted, it doesn't do word splitting; we have the complete file as one word. From now on, we do nested substitutions: you just have to remember that ${${...}}, or ${${...}}, essentially does nothing but an ordinary parameter expansion --- the whole point is the extra bits tacked on with each extra set of braces. For example, we're now going to do ${(f)"$(<$HOME/.ssh/known_hosts)"} so we get the same answer, but with the effect of putting the (f) flag at the start, which splits the result of that into lines. So we now have the entire file as an array, one line per element. ${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[0-9]*} (Clint says the ^ shouldn't be there) says take the array elements (= lines of the original file) which completely match [0-9]*, i.e. elements beginning with a digit, and remove them, which is what ${...:#...} is for. ${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[0-9]*}%%\ *} takes the result of that, and strips off from the end the largest pattern matching ' *', i.e. a space followed by anything else, in other words it leaves the largest initial string with no whitespace, which is a hostname (this is a standard ${...%%...} which even ordinary shells do, although not nested). ${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[0-9]*}%%\ *}%%,*} does another strip at the end, this time for everything from the first comma on. If there wasn't a comma, nothing changes. You could have combined the last two as ${...%%[[:blank:],]*}, or something. -- Peter Stephenson <pws@cambridgesiliconradio.com> Cambridge Silicon Radio, Unit 300, Science Park, Milton Road, Cambridge, CB4 0XL, UK Tel: +44 (0)1223 392070 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Fun zsh trick for today [not found] <no.id> 2000-06-14 13:43 ` Matthias Kopfermann 2000-06-14 15:33 ` Matthias Kopfermann @ 2000-06-14 16:31 ` Matthias Kopfermann 2 siblings, 0 replies; 12+ messages in thread From: Matthias Kopfermann @ 2000-06-14 16:31 UTC (permalink / raw) To: Peter Stephenson; +Cc: Zsh users list On Wed, Jun 14, 2000 at 04:52:10PM +0100, Peter Stephenson wrote: > [ ..] #deleted for saving space Thanks, peter! That's what i needed to follow. Nesting makes me quite dizzy but that may be better after some decades :) ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2000-06-14 16:32 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2000-06-10 22:50 Fun zsh trick for today Bart Schaefer [not found] <no.id> 2000-06-14 13:43 ` Matthias Kopfermann 2000-06-14 13:57 ` Clint Adams 2000-06-14 14:09 ` Ollivier Robert 2000-06-14 15:02 ` Fletch 2000-06-14 14:15 ` Peter Stephenson 2000-06-14 14:21 ` Peter Stephenson 2000-06-14 14:27 ` Clint Adams 2000-06-14 14:37 ` Bart Schaefer 2000-06-14 15:33 ` Matthias Kopfermann 2000-06-14 15:52 ` Peter Stephenson 2000-06-14 16:31 ` Matthias Kopfermann
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).