批量重命名来自不同路径的多个文件
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.ogg
到 music/artist/arai/music.ogg
music/artist/sako/sky.ogg
至 music/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.
我有一个文件目录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.ogg
到 music/artist/arai/music.ogg
music/artist/sako/sky.ogg
至 music/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.