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

San*_*mar 5 bash rename

当前目录中有一些无扩展名的文件(名称中没有点)。

我想像这样重命名:

filename -> filename.md
Run Code Online (Sandbox Code Playgroud)

我尝试这样做,mv * *.md但这没有帮助。

我对一个函数感兴趣,该函数接受扩展名的参数并相应地重命名,另一个用于文件执行操作。

Gil*_*il' 11

模式由 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'
Run Code Online (Sandbox Code Playgroud)

然后,您可以运行zmv以根据模式重命名文件。无论是图案和替换文本需要被引用,使它们被传递,就像是要把zmv这将扩大他们在适当的时候功能。

zmv '^*.*' '$f.md'
Run Code Online (Sandbox Code Playgroud)

注意两个参数周围的单引号:模式和替换表达式必须按字面传递给zmv函数。

^*.*表示除匹配文件之外的所有文件*.*,它是*~*.*(两者都是传统模式语法的 zsh 扩展)的快捷方式。如果你想在外面使用这个模式zmv,你需要先运行setopt extended_glob(把它放在你的里面.zshrc)。

在 bash 中

Bash 没有这么方便的工具,所以你必须求助于循环。首先,激活ksh globbing扩展;这是你应该放在你身上的东西~/.bashrc

shopt -s extglob
Run Code Online (Sandbox Code Playgroud)

现在您可以使用!(PATTERN)运算符匹配无扩展名的文件。

for x in !(*.*); do
  mv -- "$x" "$x.md"
done
Run Code Online (Sandbox Code Playgroud)

$x如果文件名包含空格或通配符,则需要双引号 arond 。在--之后的命令名称是必要的情况下,文件名开头-

在任何外壳中

如果您没有!(…)操作符,您可以遍历所有文件并测试循环内的每个文件名。

for x in *; do
  case "$x" in
    *.*) ;;         # skip this file
    *) mv -- "$x" "$x.md";;
  esac
done
Run Code Online (Sandbox Code Playgroud)