Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Zsh functionality similar to Perl 'map'?
- X-seq: zsh-users 14587
- From: Philippe Troin <phil@xxxxxxxx>
- To: "Benjamin R. Haskell" <zsh@xxxxxxxxxx>
- Subject: Re: Zsh functionality similar to Perl 'map'?
- Date: 20 Nov 2009 12:31:07 -0800
- Cc: Zsh Users <zsh-users@xxxxxxx>
- In-reply-to: <alpine.LNX.2.01.0911201034070.24555@xxxxxxxxxxx>
- List-help: <mailto:zsh-users-help@zsh.org>
- List-id: Zsh Users List <zsh-users.zsh.org>
- List-post: <mailto:zsh-users@zsh.org>
- Mail-copies-to: nobody
- Mailing-list: contact zsh-users-help@xxxxxxx; run by ezmlm
- References: <alpine.LNX.2.01.0911201034070.24555@xxxxxxxxxxx>
- Sender: phil@xxxxxxxx
"Benjamin R. Haskell" <zsh@xxxxxxxxxx> writes:
> I frequently find myself diff'ing files that have minor differences I'd
> like to filter out. E.g. this gem from my historyfile:
>
> diff -ur =(LD_LIBRARY_PATH=/opt/chromium.org/lib ldd /opt/chromium.org/chrome-linux/chrome | perl -lpwe 's/\(.*\)//' | sort | uniq) =(ldd /opt/chromium.org/chrome-linux/chrome | perl -lpwe 's/\(.*\)//' | sort | uniq)
>
> (That is: find the differences in the loaded libraries for the Linux
> version of Chromium, depending on whether LD_LIBRARY_PATH contains
> /opt/chromium.org/lib)
>
> These diffs follow the general pattern:
>
> diff -ur =(do-something-1 | filter) =(do-something-2 | filter)
>
> My question is: is there a nice way to 'map' this, so I don't have to
> type/edit the '| filter' portion twice? The filter portion often changes,
> and is usually incrementally developed.
>
> (E.g. in the Chromium case, I have the consecutive commands:
> diff -ur =(LD_LIBRARY_PATH=/opt/chromium.org/lib ldd /opt/chromium.org/chrome-linux/chrome) =(ldd /opt/chromium.org/chrome-linux/chrome)
> diff -ur =(LD_LIBRARY_PATH=/opt/chromium.org/lib ldd /opt/chromium.org/chrome-linux/chrome | perl -lpwe 's/\(.*\)//') =(ldd /opt/chromium.org/chrome-linux/chrome | perl -lpwe 's/\(.*\)//')
> diff -ur =(LD_LIBRARY_PATH=/opt/chromium.org/lib ldd /opt/chromium.org/chrome-linux/chrome | perl -lpwe 's/\(.*\)//' | sort | uniq) =(ldd /opt/chromium.org/chrome-linux/chrome | perl -lpwe 's/\(.*\)//' | sort | uniq)
> )
>
> I suspect most people's preferred solutions will involve functions...
> something along the lines of:
>
> function filter () { perl -lpwe 's/\(.*\)//' | sort | uniq } ; diff -ur =(blah-1 | filter) =(blah-2 | filter)
>
> But I was wondering if there was another way that didn't disrupt the flow
> as much. (I dislike that the filter function ends up getting 'fronted',
> to use the linguistic term. It's kind of like saying, "A butter knife, he
> spread the jam with it and the jelly with it," when I'd rather say, "He
> spread the jam and the jelly with a butter knife," or even "He spread
> with a butter knife the jam and the jelly.")
>
> Plus, this isn't the best or most-general example. Often the '| filter'
> part is actually run on two different files, rather than piped-in. (So:
> diff -ur =(filter file1) =(filter file2)
> )
You could always do this:
filterdiff () {
emulate -L zsh
local i a
local -a opts
local -a args
while [[ $# > 0 ]]
do
a=$1
shift
case $a in
(--) args=($args $*)
break
;;
(-?*) opts=($opts $a)
;;
(*) args=($args $a)
;;
esac
done
if (( $#args != 3 ))
then
print "usage: $0 [options] <filter> <file1> <file2>" >&2
return 1
fi
diff $opts -- <( eval $args[1] < $args[2] ) <( eval $args[1] < $args[3] )
}
Use it like this:
filterdiff 'tr a-z A-Z | tac' /etc/passwd /etc/hosts
You have to quote the filter of course...
> Ideally, it'd end up as something like:
>
> diff -ur =({do-something1,do-something2} | filter)
> or
> diff -ur =(filter {file1,file2})
>
> ...and, yes, I know that's a *huge* stretch. And, maybe my Perl bias for
> map'ping everything is showing, but still, figured I'd ask.
I'm afraid this fancy syntax won't be possible. Well, you could by
hacking the completion system, but that would be unmaintainable
Phil.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author