Patterns are matched by the shell, not by the command, so what you tried had no chance to work: first the shell expands *
to all files (not just the extensionless ones: you never said anything about the files not having a .
in their name), and *.md
to all files whose name in .md
; then the shell passes the concatenation of the two lists to the mv
command.
In zsh
In zsh, run the following command once (put them in your ~/.zshrc
for the future):
autoload -U zmv
# you don't need the following two now, but put them also in your .zshrc
alias zcp='zmv -C'
alias zln='zmv -L'
You can then run zmv
to rename files according to a pattern. Both the pattern and the replacement text need to be quoted so that they are passed-as is to the zmv
function which will expand them in due course.
zmv '^*.*' '$f.md'
Note the single quotes around both arguments: the pattern and the replacement expression must be passed literally to the zmv
function.
^*.*
means all files except the ones matching *.*
, it's a shortcut for *~*.*
(both are zsh extensions to the traditional pattern syntax). If you want to use this pattern outside zmv
, you need to run setopt extended_glob
first (put that in your .zshrc
too).
In bash
Bash has no such convenient tool, so you have to resort to a loop. First, activate ksh globbing extensions; that's something you should put in yout ~/.bashrc
.
shopt -s extglob
Now you can use the !(PATTERN)
operator to match extensionless files.
for x in !(*.*); do
mv -- "$x" "$x.md"
done
The double quotes arond $x
are necessary in case the file names contain whitespace or globbing characters. The --
after the command name is necessary in case a file name begins with -
.
In any shell
If you don't have the !(…)
operator, you can loop over all files and test each file name inside the loop.
for x in *; do
case "$x" in
*.*) ;; # skip this file
*) mv -- "$x" "$x.md";;
esac
done
case
items. I think I got into the habit of using:
from an old shell that didn't. I don't remember which one that would be. – Gilles 'SO- stop being evil' Mar 23 '13 at 22:33