Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Potential improvement for zmv
- X-seq: zsh-workers 16919
- From: Wayne Davison <wayned@xxxxxxxxxxxxxxxxxxxxx>
- To: Zsh Workers <zsh-workers@xxxxxxxxxx>
- Subject: Potential improvement for zmv
- Date: Wed, 27 Mar 2002 16:48:08 -0800 (PST)
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
I implemented a new option for zmv: -W. This works just like -w, with
the additional feature that it automatically transforms wildcards in the
replacement pattern into a sequential series of ${1} .. ${N} vars. This
allows you to do things like this:
alias mmv='noglob zmv -W'
mmv *.orig orig/*
mmv **/*.txt **/*.lis
Since I'm still a novice shell programmer, some of you wizards out
there can undoubtedly improve the shell code I wrote. For instance,
I don't know if it's possible to increment $N inside a global search
and replace (I resorted to using a loop).
Here's the patch. Let me know what you think.
..wayne..
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: zsh/Functions/Misc/zmv
--- zsh/Functions/Misc/zmv 28 Aug 2001 20:28:18 -0000 1.9
+++ zsh/Functions/Misc/zmv 28 Mar 2002 00:45:34 -0000
@@ -13,9 +13,14 @@
# path. Note that you need to write it like this; you can't get away with
# '(**/*).txt'.
# zmv -w '**/*.txt' '$1$2.lis'
-# This is the lazy version of the one above; zsh picks out the patterns
-# for you. The catch here is that you don't need the / in the replacement
-# pattern. (It's not really a catch, since $1 can be empty.)
+# noglob zmv -W **/*.txt **/*.lis
+# These are the lazy version of the one above; with -w, zsh inserts the
+# parentheses for you in the search pattern, and with -W it also inserts
+# the numbered variables for you in the replacement pattern. The catch
+# in the first version is that you don't need the / in the replacement
+# pattern. (It's not really a catch, since $1 can be empty.) Note that
+# -W actuall inserts ${1}, ${2}, etc., so it works even if you put a
+# number after a wildcard (such as zmv -W '*1.txt' '*2.txt').
# zmv -C '**/(*).txt' ~/save/'$1'.lis
# Copy, instead of move, all .txt files in subdirectories to .lis files
# in the single directory `~/save'. Note that the ~ was not quoted.
@@ -91,6 +96,8 @@
# where <oldname> and <newname> are filenames generated.
# -w Pick out wildcard parts of the pattern, as described above, and
# implicitly add parentheses for referring to them.
+# -W Just like -w, with the addition of turning wildcards in the
+# replacement pattern into sequential ${1} .. ${N} references.
# -C
# -L
# -M Force cp, ln or mv, respectively, regardless of the name of the
@@ -116,12 +123,12 @@
local f g args match mbegin mend files action myname tmpf opt exec
local opt_f opt_i opt_n opt_q opt_Q opt_s opt_M opt_C opt_L
-local opt_o opt_p opt_v opt_w MATCH MBEGIN MEND
+local opt_o opt_p opt_v opt_w opt_W MATCH MBEGIN MEND
local pat repl errstr fpat hasglobqual opat
typeset -A from to
integer stat
-while getopts ":o:p:MCLfinqQsvw" opt; do
+while getopts ":o:p:MCLfinqQsvwW" opt; do
if [[ $opt = "?" ]]; then
print -P "%N: unrecognized option: -$OPTARG" >&2
return 1
@@ -173,7 +180,7 @@
return 1
fi
-if [[ -n $opt_w ]]; then
+if [[ -n $opt_w || -n $opt_W ]]; then
# Parenthesise all wildcards.
local newpat
# Well, this seems to work.
@@ -183,9 +190,27 @@
(#m)(\*\*#\/|[*?]|\<[0-9]#-[0-9]#\>|\[(\[:[a-z]##:\]|\\\[|\\\]|[^\[\]]##)##\])\##\
/($MATCH)}"
if [[ $newpat = $pat ]]; then
- print -P "%N: warning: no wildcards were found" >&2
+ print -P "%N: warning: no wildcards were found in search pattern" >&2
else
pat=$newpat
+ fi
+ if [[ -n $opt_W ]]; then
+ # Turn wildcards into ${1} .. ${N} references.
+ local N=1
+ local tmp=X
+ newpat=$repl
+ while [[ $newpat != $tmp ]]; do
+ tmp=$newpat
+ newpat="${newpat/\
+(#m)(\*\*#\/|[*?]|\<[0-9]#-[0-9]#\>|\[(\[:[a-z]##:\]|\\\[|\\\]|[^\[\]]##)##\])\##\
+/\${$N\}}"
+ (( N++ ))
+ done
+ if [[ $newpat = $repl ]]; then
+ print -P "%N: warning: no wildcards were found in replacement pattern" >&2
+ else
+ repl=$newpat
+ fi
fi
fi
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Messages sorted by:
Reverse Date,
Date,
Thread,
Author