给出以下文件/目录结构:
/photos/1/original/filename1.jpg
/photos/1/thumb/filename1.jpg
/photos/2/original/filename2.jpg
/photos/2/thumb/filename2.jpg
/photos/3/original/filename3.jpg
/photos/3/thumb/filename3.jpg
...等我正在寻找将文件/目录结构转换为的正则表达式:
/photos/1/original.jpg
/photos/1/thumb.jpg
/photos/2/original.jpg
/photos/2/thumb.jpg
/photos/3/original.jpg
/photos/3/thumb.jpg
...等我有脚本来用ruby或perl重命名文件...只是缺少正确的正则表达式。
Perl解决方案
$newfn = $oldfn;
$newfn =~ s/(original|thumb)[^\.]*/$1/;
rename($oldfn, $newfn);
根据要求,匹配所有关键字,而不仅仅是“原始”或“拇指”,只要/ photos / nn保持不变:
$newfn = $oldfn;
$newfn =~ s?(photos/\d+/[^/]*)/[^\.]*?$1?;
rename($oldfn, $newfn);
采用此解决方案还可以删除目录(如果它们为空)
$newfn = $oldfn;
$newfn =~ s?(/photos/\d+/)([^/]*)/[^\.]*?$1$2?;
rename($oldfn, $newfn);
unlink($1$2);
我不确定如果要取消链接时目录不为空,该怎么办。
这里是红宝石解决方案:
require 'fileutils'
old_file = "/photos/1/original/filename1.jpg"
new_file = old_file.sub(/(\d+)\/(\w+)\/.+(\.\w+)/, '\1/\2\3')
FileUtils.mv(old_file, new_file)
适应Paul Tomblin的解决方案并提供更通用的重命名:
my $newfn = $oldfn;
$newfn =~ s%(/\d+/[^/]+)/[^/]+(\.[^./]+)$%$1$2%;
让我们用'x'选项扩展它:
$newfn =~ s%
( # start remembering
/\d+/ # /397/
[^/]+ # original, thumb, othername, ...
) # stop remembering
/ # directory
[^/]+ # filename within directory
(\.[^./]+)$ # remember extension matching to end of name
%
$1$2 # /397/original.png
%x;
((未经测试-可能有错别字。)
注意:虽然这不能直接回答您的问题,但我认为您仍然会发现这很有用。 Linux和cygwin都具有命令“ rename
”和“ mmv
”(多次移动),可以满足此需求。给定目录结构和请求,您可以轻松使用rename
命令来解决此问题:
cd /photos/1/original
rename filename original *.jpg
mv *.jpg ..
cd ../thumb
rename filename thumb *.jpg
mv *.jpg ..
cd ../2
.... (repeat for other directories)
您必须检查mmv
的手册页,但看起来您可以做类似的事情(未经测试):
cd /photos
mmv "*/original/filename*.jpg" "./#1/original#2.jpg"
mmv "*/thumb/filename*.jpg" "./#1/thumb#2.jpg"
并且这将重命名文件并将文件移到要处理的整个文件树的所需目录中。双引号是必需的。