如何更改目录中所有文件的扩展名?

如何更改目录中所有文件的扩展名?

当前目录下有一些无扩展名的文件(文件名中不带点)。

我想像这样重命名:

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

它也可以变成一个函数。

相关内容