如何将文件名提取为两部分,一部分放入目录,另一部分放入目录?
How do I extract a file name into 2 parts, making one into directory and the other one inside of it?
我正在尝试按艺术家和姓名对所有 mp3 文件进行排序。目前,它们在 1 个巨大的文件名中。
例如艺术家 - 歌曲名称.mp3
我想将其转换为
Artist/Song 名称.mp3
以下是我目前尝试过的方法。在这种情况下,我使用的是名为 "hi\ -\ hey":
的测试文件
#!/bin/bash
# filters by all .mp3 extensions in the current working directory
for f in *.mp3; do
# extract artist and song name and remove spaces
artist=${f% -*}
song=${f#*- }
#make directory with the extracted artist name and move + rename the file into the directory
mkdir -p $artist
mv $f $artist/$song;
done
出于某种原因,它创建了一个目录,其中包含歌曲名称而不是艺术家,此外还有大量错误:
mv: cannot move 'hey.mp3' to a subdirectory of itself, 'hey.mp3/hey.mp3'
mv: cannot stat 'hi': No such file or directory
mv: cannot stat '-': No such file or directory
mv: 'hey.mp3/hi' and 'hey.mp3/hi' are the same file
mv: cannot stat '-': No such file or directory
假设有很多文件,使用管道而不是 for 循环执行此操作可能要快得多。这具有避免复杂的 bash
特定语法和使用核心 unix/linux 命令行程序的额外优势。
find *-*.mp3 |
sed 's,\([^-]\+\)\s*-\s*\(.*\),mkdir -p ""; mv "&" ""/"",' |
bash
解释:
此find
查找当前目录下所有匹配-.mp3的文件
此 sed
命令将每一行更改为命令字符串,例如:
aaa - bbb.mp3
->
mkdir -p "aaa"; mv "aaa - bbb.mp3" "aaa"/"bbb.mp3"
bash
命令运行每个命令字符串。
你可以试试这个。
#!/usr/local/bin/bash
for f in *.mp3
do
artist=`echo $f | awk '{print }' FS=-`
song=`echo $f | awk '{print }' FS=-`
mkdir -p $artist
mv $artist-$song $song
mv $song ./$artist
done
这里我使用了两个变量艺术家和歌曲。因为你的测试文件名是 "hi\ -\ hey" 所以我将 awk 分隔符更改为“-”以根据它存储变量。
我们不需要使用 awk..通过使用 bash 参数扩展....它正在工作。
#!/usr/local/bin/bash
for f in *.mp3
do
artist=`echo ${f%-*}`
song=`echo ${f#*-}`
mkdir -p $artist
mv $artist-$song $song
mv $song ./$artist
done
到目前为止,最简单的方法是使用 rename
a.k.a。 Perl rename
.
基本上,你想用正斜杠目录分隔符替换序列 SPACE-DASH-SPACE,所以命令是:
rename --dry-run -p 's| - |/|' *mp3
示例输出
'Artist - Song name.mp3' would be renamed to 'Artist/Song name.mp3'
'Artist B - Song name 2.mp3' would be renamed to 'Artist B/Song name 2.mp3'
如果看起来正确,只需再次删除 --dry-run
和 运行 即可。使用 rename
的好处是:
- 它可以在您 运行 之前进行干式 运行 测试
- 它将使用
-p
选项创建所有必要的目录
- 它不会在没有警告的情况下破坏(覆盖)文件
- 您可以使用 Perl 的全部功能,并且可以根据需要进行复杂的重命名。
请注意,您可以在 macOS 上使用 homebrew 安装:
brew install rename
以防万一您没有 rename
实用程序。修复您的原始脚本。
for f in *.mp3; do
# extract artist and song name and remove spaces
artist=${f%% -*}
song=${f##*- }
#make directory with the extracted artist name and move + rename the file into the directory
echo mkdir -p -- "$artist" && echo mv -- "$f" "$artist/$song"
done
- 如果您对输出感到满意,请删除
echo
。
我正在尝试按艺术家和姓名对所有 mp3 文件进行排序。目前,它们在 1 个巨大的文件名中。 例如艺术家 - 歌曲名称.mp3 我想将其转换为 Artist/Song 名称.mp3
以下是我目前尝试过的方法。在这种情况下,我使用的是名为 "hi\ -\ hey":
的测试文件#!/bin/bash
# filters by all .mp3 extensions in the current working directory
for f in *.mp3; do
# extract artist and song name and remove spaces
artist=${f% -*}
song=${f#*- }
#make directory with the extracted artist name and move + rename the file into the directory
mkdir -p $artist
mv $f $artist/$song;
done
出于某种原因,它创建了一个目录,其中包含歌曲名称而不是艺术家,此外还有大量错误:
mv: cannot move 'hey.mp3' to a subdirectory of itself, 'hey.mp3/hey.mp3'
mv: cannot stat 'hi': No such file or directory
mv: cannot stat '-': No such file or directory
mv: 'hey.mp3/hi' and 'hey.mp3/hi' are the same file
mv: cannot stat '-': No such file or directory
假设有很多文件,使用管道而不是 for 循环执行此操作可能要快得多。这具有避免复杂的 bash
特定语法和使用核心 unix/linux 命令行程序的额外优势。
find *-*.mp3 |
sed 's,\([^-]\+\)\s*-\s*\(.*\),mkdir -p ""; mv "&" ""/"",' |
bash
解释:
此find
查找当前目录下所有匹配-.mp3的文件
此 sed
命令将每一行更改为命令字符串,例如:
aaa - bbb.mp3
->
mkdir -p "aaa"; mv "aaa - bbb.mp3" "aaa"/"bbb.mp3"
bash
命令运行每个命令字符串。
你可以试试这个。
#!/usr/local/bin/bash
for f in *.mp3
do
artist=`echo $f | awk '{print }' FS=-`
song=`echo $f | awk '{print }' FS=-`
mkdir -p $artist
mv $artist-$song $song
mv $song ./$artist
done
这里我使用了两个变量艺术家和歌曲。因为你的测试文件名是 "hi\ -\ hey" 所以我将 awk 分隔符更改为“-”以根据它存储变量。
我们不需要使用 awk..通过使用 bash 参数扩展....它正在工作。
#!/usr/local/bin/bash
for f in *.mp3
do
artist=`echo ${f%-*}`
song=`echo ${f#*-}`
mkdir -p $artist
mv $artist-$song $song
mv $song ./$artist
done
到目前为止,最简单的方法是使用 rename
a.k.a。 Perl rename
.
基本上,你想用正斜杠目录分隔符替换序列 SPACE-DASH-SPACE,所以命令是:
rename --dry-run -p 's| - |/|' *mp3
示例输出
'Artist - Song name.mp3' would be renamed to 'Artist/Song name.mp3'
'Artist B - Song name 2.mp3' would be renamed to 'Artist B/Song name 2.mp3'
如果看起来正确,只需再次删除 --dry-run
和 运行 即可。使用 rename
的好处是:
- 它可以在您 运行 之前进行干式 运行 测试
- 它将使用
-p
选项创建所有必要的目录 - 它不会在没有警告的情况下破坏(覆盖)文件
- 您可以使用 Perl 的全部功能,并且可以根据需要进行复杂的重命名。
请注意,您可以在 macOS 上使用 homebrew 安装:
brew install rename
以防万一您没有 rename
实用程序。修复您的原始脚本。
for f in *.mp3; do
# extract artist and song name and remove spaces
artist=${f%% -*}
song=${f##*- }
#make directory with the extracted artist name and move + rename the file into the directory
echo mkdir -p -- "$artist" && echo mv -- "$f" "$artist/$song"
done
- 如果您对输出感到满意,请删除
echo
。