当前目录下有一些无扩展名的文件(文件名中不带点)。
我想像这样重命名:
filename -> filename.md
我尝试这样做,mv * *.md
但这没有帮助。
我对一个函数感兴趣,该函数接受扩展名的参数并相应地重命名,另一个函数则用于对文件执行操作。
答案1
模式是由 shell 匹配的,而不是由命令匹配的,因此您尝试的方法没有机会工作:第一的shell 扩展*
到所有文件(不仅仅是无扩展名的文件:您从未说过任何有关.
名称中没有 a 的文件),以及*.md
名称为.md
;的所有文件。然后 shell 将两个列表的串联传递给mv
命令。
在zsh中
在 zsh 中,运行以下命令一次(将它们放在您的~/.zshrc
将来):
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'
然后你可以运行zmv
根据模式重命名文件。这俩图案并且需要引用替换文本,以便将它们按原样传递给将zmv
在适当的时候扩展它们的函数。
zmv '^*.*' '$f.md'
请注意两个参数周围的单引号:模式和替换表达式必须按字面意思传递给函数zmv
。
^*.*
表示除了匹配的文件之外的所有文件*.*
,它是*~*.*
(两者都是传统模式语法的 zsh 扩展)的快捷方式。如果您想在外部使用此模式zmv
,则需要setopt extended_glob
先运行(也将其放入您的中.zshrc
)。
在bash中
Bash 没有这样方便的工具,所以你必须求助于循环。首先,激活 ksh globbing 扩展;那是你应该放在你身上的东西~/.bashrc
。
shopt -s extglob
现在您可以使用!(PATTERN)
运算符来匹配无扩展名文件。
for x in !(*.*); do
mv -- "$x" "$x.md"
done
$x
如果文件名包含空格或通配符,则需要使用双引号。如果--
文件名以-
.
在任何外壳中
如果没有!(…)
运算符,您可以循环所有文件并测试循环内的每个文件名。
for x in *; do
case "$x" in
*.*) ;; # skip this file
*) mv -- "$x" "$x.md";;
esac
done
答案2
你可以用(有时rename
会附带的那个)来做到这一点perl
重命名 prename
)。如果目录中还有其他文件,您需要使用 extglob 排除这些文件,如下所示:
shopt -s extglob
rename s/$/.md/ -- !(*.*)
答案3
找到了一个简短的答案这里(这也支持重命名,这就是我找到此页面时正在寻找的):
for f in *.OLDNAME; do mv $f `basename $f .OLDNAME`.NEWNAME; done;
当然,这也适用于添加或删除扩展:
# Adding extension
for f in *; do mv $f ${f}.NEWNAME; done; # No need to use basename here -- just adding a new extension
# Removing extension
for f in *.OLDNAME; do mv $f `basename $f .OLDNAME`; done;
答案4
可能有一种更简单的方法,但是这个方法相当简单,并且通用形式适用于各种目的:
for name in *; do
if [ -f "$name" ]; then
mv -- "$name" "$name.md"
fi
done
它也可以变成一个函数。