批量重命名来自不同路径的多个文件

Batch rename multiple files from different path

我有一个文件目录music/artist/{random_name}/{random_music}.ogg

{random_name} 中有很多文件夹和不同类型的音乐标题 {random_music}

所以,我想将 {random_music}.ogg 重命名为 music.ogg。每个 {random_name} 个文件夹只有一个 .ogg 文件。

我已经尝试使用 Bash 脚本几个小时了,但没找到答案。

for f in ../music/artist/*/*.ogg
do
  echo mv  "$f" "${f/.*.ogg/music.ogg}"
done

它只会重命名我当前目录中的文件,这将要求 replace/overwrite。

我的目标是,我想将所有 {random_music}.ogg 文件重命名为 music.ogg 以及它们各自的目录,例如

music/artist/arai/blue.oggmusic/artist/arai/music.ogg

music/artist/sako/sky.oggmusic/artist/sako/music.ogg

您的模式替换不正确。因为你所有的路径都以 .. 开头,.*.ogg 实际上匹配 整个路径 ,所以 每个 文件都会变成 music.ogg 在你的当前目录中。

你想要 ${f/\/*.ogg/music.ogg},或者更好,${f%/*}/music.ogg。这大致相当于 "$(dirname "$f")"/music.ogg.

我通常用这个:

for f in ../music/artist/*/*.ogg
do
    dest="${f/.*.ogg/music.ogg}"
    if [[ $f != "$dest" ]] # nothing to do if name doesn't change
    then 
        if [[ -a $dest ]]
        then
            printf 'WARNING: File already exists: %s\n' "$dest"
        else
            mv "$f" "$dest"
        fi
    fi
done

您可以像这样更改您的代码

for f in ../music/artist/*/*.ogg
do
  echo mv $f "$(dirname "$f")"/music.ogg
done

此处 dirname 将从您的变量中提取目录名称,您可以将其附加到您的 music.ogg 以获得所需的结果。

对于您提供的示例路径

如果$f等于music/artist/arai/blue.ogg,那么结果将是

mv music/artist/arai/blue.ogg music/artist/arai/music.ogg

希望对您有所帮助:

之前:

[root@user]# tree music
music
└── artist
    ├── df
    │   └── mp.ogg
    ├── gh
    │   └── pl.ogg
    ├── jk
    │   └── gl.ogg
    ├── po
    │   └── ui.ogg
    ├── ty
    │   └── lk.ogg
    └── ui
        └── dh.ogg

7 directories, 6 files

源代码:

#!/bin/bash

for i in `ls -ld music/artist/* | awk '{print }'`
do
        mv $i/*ogg $i/music.ogg

done

执行后:

music
└── artist
    ├── df
    │   └── music.ogg
    ├── gh
    │   └── music.ogg
    ├── jk
    │   └── music.ogg
    ├── po
    │   └── music.ogg
    ├── ty
    │   └── music.ogg
    └── ui
        └── music.ogg

7 directories, 6 files

如您所见,所有文件都已正确重命名。

find ../music/artist/ -type f -name "*.ogg" -exec bash -c 'mydir=`dirname {}`;mv {} $mydir/music.ogg' \;

这是一个应该有效的单行。它实现了 find 命令的 exec 选项,然后获取目录名称并将原始文件重命名为 music.ogg.