The zshcompsys
man page has a similar example to get case insensitive completion
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}'
Changing it to make -
and _
equivalent seems to do what you want
zstyle ':completion:*' matcher-list '' 'm:{-_}={_-}'
Or you could add it to the first example, and get case insensitive completion too
zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z-_}={A-Za-z_-}'
Don't use find
for this - whichever way you go with find
you'll need something like a single mv
per file. That's a lot of processes, and to no benefit. This is not to mention that it is simply more difficult to do that way. That's my opinion, anyway.
I would use a stream or a batch tool, and tend to prefer pax
:
cd -P . && mkdir ../newmp4 &&
pax -rwls'|?|_|g' . "${PWD%/*}/newmp4"
If you can create the directory ../newmp4
, that little script will mirror the tree rooted in .
to the directory just created with hardlinks, but will have replaced every ?
occurring in any filename with an underscore in the meanwhile.
One advantage to this is that both trees continue to exist afterward - none of the dentries rooted in the current directory for those files are affected - they are only altered in the mirrored version of the tree. And so you can inspect the results afterward before deciding which version of the tree to remove. If anything were to go wrong during the operation - there's no harm done.
This does, however, require an fs which supports hardlinks and which has at least as many remaining free inodes as there are child directories of .
+2, and assumes that ..
.
and all children of .
share the same filesystem mount.
Practically the same effect might be got with rsync
, I think, though I don't believe it is as simply done. If you don't have pax
(even if you really should), you can just get it. mirabilos maintains the (to my knowledge) most commonly used version on linux systems.
Best Answer
What you want here is the equivalent of the regexp
+
operator which in zsh withextendedglob
on (andzmv
does enableextendedglob
) is the##
glob operator.The
:s/.../.../
modifier from csh doesn't do pattern matching unless you set thehistsubstpattern
option.zmv
doesn't set that option and resets the options to a sane default, so you can't use it there. The next version ofzsh
(whether that's 5.10 or 6.0) will have:S
(actually on my request and for that very purpose) which does pattern matching unconditionally, so with those, you'll be able to do:But with any version of zsh, you can also use the ksh-style
${param//pattern/replacement}
instead:Note that
--
is not necessary here as the first argument doesn't start with-
.