tl; dr如何将文件/ foo / bar重命名为/ foo / bar-foo,以获取许多不同文件夹中的许多不同文件?
现在,我母亲的音乐是在一个32GB的笔式驱动器上,她已插入她的汽车。在笔式驱动器上,有一些以艺术家名字命名的文件夹,这些文件夹中的文件夹是由专辑名称标记的文件夹,里面是歌曲本身。当我的妈妈在她的汽车中播放音乐时,汽车一次只播放一个文件夹中的音乐。她更喜欢所有歌曲的随机播放。我的解决方案是
cp ./*/*/*/* /otherfolderonmycomputer
将所有歌曲文件放入一个文件夹,然后删除笔式驱动器上的所有内容,然后将该文件夹复制回其中。然而,有一个问题。她在不同的专辑中有不同版本的每首歌。这些歌曲彼此具有相同的标题,并且cp命令想要覆盖其中一个。我想出的解决方案是将每个音乐文件重命名为SongTitle-AlbumName,这样cp就不会想要覆盖任何内容,这样她就能分辨出她正在收听的每首歌曲的哪个版本。我该怎么做?
答案 0 :(得分:2)
它当然可以编写脚本(选项#1),因为它有无限的可能性; 'awk'是众多选项之一(用(例如)find * -name \*.mp3
替换硬编码的“foo / bar / ...”):
$ for x in foo/bar/{abc,xyz}/{f1,f2,f3}.mp3
do
newfile=$( echo $x | awk -F/ '{ print $3 "-" $2 "-" $NF }')
echo mv $x foo/$newfile
done
mv foo/bar/abc/f1.mp3 foo/abc-bar-f1.mp3
mv foo/bar/abc/f2.mp3 foo/abc-bar-f2.mp3
mv foo/bar/abc/f3.mp3 foo/abc-bar-f3.mp3
mv foo/bar/xyz/f1.mp3 foo/xyz-bar-f1.mp3
mv foo/bar/xyz/f2.mp3 foo/xyz-bar-f2.mp3
mv foo/bar/xyz/f3.mp3 foo/xyz-bar-f3.mp3
但也许更好,更简单,更灵活(选项#2)将使用pytagsfs,它会根据您定义的规则创建虚拟(融合)文件系统,这会使您的目录结构“显示”但是你想要它。完成后,将该虚拟目录结构复制到物理目录结构中。这样,您可以调整虚拟布局,查看它,然后将其复制到笔式驱动器“make is so”,可以这么说。 (但是,你可能需要一个相当宽敞的工作空间。)
$ tree foo-orig # or ls -R, whatever
... your files...
$ mkdir by-genre
$ pytagsfs -o format='/%g/%a - %t.%e' foo-orig by-genre
$ tree by-genre
... in different dir structure
$ cp -r by-genre foo-new # make it so
答案 1 :(得分:1)
如何将文件/ foo / bar重命名为/ foo / bar-foo?
mv /foo/bar /foo/bar-foo
使用文件夹名称以递归方式对多个文件/文件夹进行查看: http://www.linuxquestions.org/questions/linux-general-1/how-to-recursively-rename-files-using-their-directory-name-pattern-367807/
答案 2 :(得分:1)
使用perl
的一种方式:
script.pl
的内容:
use warnings;
use strict;
use File::Find;
use File::Copy;
## Accept one dir with files as input argument.
die qq[Usage: perl $0 <dir>\n] unless @ARGV == 1;
my $arg_dir = $ARGV[0];
find( \&wanted, $arg_dir );
sub wanted {
## Return if file is special.
return unless -f;
## Get last dir of current path.
my ($album) = $File::Find::dir =~ m|/([^/]+)$|;
## Get extension of the file (supposed mp3 if music).
my ($extension) = ($File::Find::name =~ m|.*\.([^.]+)$|);
## Remove the extension, because I will add the album name just before it.
s/\.[^.]+$//;
## Rename each file into base dir passed as argument to the script.
#rename( $File::Find::name, $arg_dir . qq[/] . $_ . qq[-] . $album . qq[.] . $extension ) || die;
copy( $File::Find::name, $arg_dir . qq[/] . $_ . qq[-] . $album . qq[.] . $extension ) || die;
}
运行脚本:将所有音乐文件的基本路径作为参数传递,脚本将搜索目录子树,搜索每个移动的普通文件并将其重命名为基本路径:
perl script.pl ~/temp/music/
考虑到脚本的最后两条指令,我已copy(...)
取消注释,它将重命名新文件而不删除旧文件。确定它有效后,请注释该行并取消注释前一行rename(...)
。它们很相似,但复制显然更安全。
答案 3 :(得分:1)
有点不正统,但你可以尝试这样的事情 -
while IFS='$\n' read line ; do
mv $line $line$(sed 's#/#-#g' <<< $(dirname ${line#.}));
done < <(find . -type f -name "*.mp3")
<强>之前:强>
[jaypal:~/Temp] find . -type f -name "*.mp3"
./c/c1/c.mp3
./c/c2/cc.mp3
运行脚本后
[jaypal:~/Temp] find . -type f -name "*.mp3*"
./c/c1/c.mp3-c-c1
./c/c2/cc.mp3-c-c2