我有一个名为“images”的目录,里面装满了大约一百万张图片。是的。
我想编写一个shell命令来将所有这些图像重命名为以下格式:
原始:`filename.jpg` 新的:`/f/i/l/filename.jpg`
有什么建议吗?
谢谢, 丹
我想编写一个shell命令来将所有这些图像重命名为以下格式:
原始:`filename.jpg` 新的:`/f/i/l/filename.jpg`
有什么建议吗?
谢谢, 丹
for i in *.*; do mkdir -p ${i:0:1}/${i:1:1}/${i:2:1}/; mv $i ${i:0:1}/${i:1:1}/${i:2:1}/; done;
${i:0:1}/${i:1:1}/${i:2:1}
这一部分可能是一个变量,或者可以更短更简洁,但是上面的命令已经完成了任务。你可能会遇到性能问题,但如果你真的想使用它,请将*.*
缩小到较少的选项(例如:a*.*
,b*.*
或者适合你的选项)。编辑: 根据 Dan 的提示,在 mv
前加上 $
,即 i
变成 $i
。$ echo "test.jpg" | sed -e 's/^\(\(.\)\(.\)\(.\).*\)$/\2\/\3\/\4\/\1/'
t/e/s/test.jpg
for f in *; do
mv -i "$f" "$(echo "$f" | sed -e 's/^\(\(.\)\(.\)\(.\).*\)$/\2\/\3\/\4\/\1/')"
done
或者,如果您无法使用bash $(
语法:
for f in *; do
mv -i "$f" "`echo "$f" | sed -e 's/^\(\(.\)\(.\)\(.\).*\)$/\2\/\3\/\4\/\1/'`"
done
然而,考虑到文件的数量,你可能只想使用 Perl,因为那样会产生大量的 sed 和 mv 进程:
#!/usr/bin/perl -w
use strict;
# warning: untested
opendir DIR, "." or die "opendir: $!";
my @files = readdir(DIR); # can't change dir while reading: read in advance
closedir DIR;
foreach my $f (@files) {
(my $new_name = $f) =~ s!^((.)(.)(.).*)$!$2/$3/$4/$1/;
-e $new_name and die "$new_name already exists";
rename($f, $new_name);
}
Perl的限制在于只能在同一文件系统中移动文件,但你可以使用File::Copy::move
来解决这个问题。
-f $f or next;
,在shell循环中类似)。 - derobert#!/bin/bash
base=base
mkdir -p $base/shorts
for n in *
do
if [ ${#n} -lt 3 ]
then
mv $n $base/shorts
else
dir=$base/${n:0:1}/${n:1:1}/${n:2:1}
mkdir -p $dir
mv $n $dir
fi
done
我建议使用一个简短的Python脚本。大多数shell工具可能无法处理这么多输入(虽然xargs可能会有效)。稍后会更新示例。
#!/usr/bin/python
import os, shutil
src_dir = '/src/dir'
dest_dir = '/dest/dir'
for fn in os.listdir(src_dir):
os.makedirs(dest_dir+'/'+fn[0]+'/'+fn[1]+'/'+fn[2]+'/')
shutil.copyfile(src_dir+'/'+fn, dest_dir+'/'+fn[0]+'/'+fn[1]+'/'+fn[2]+'/'+fn)
任何在shell中使用通配符语法的解决方案都很可能因您拥有的大量文件而失败。在当前提出的解决方案中,Perl 的解决方案可能是最好的。
不过,您可以轻松地调整任何一个 shell 脚本方法来处理任意数量的文件,方法如下:
ls -1 | \
while read filename
do
# insert the loop body of your preference here, operating on "filename"
done
for f in *
可以很好地处理1,000,000个文件。虽然速度慢一些,但是它可以正常工作。 - derobert
${i:0:1}
语法是 Bash 的特有语法,在 Linux 上可能没问题,但以防万一... - derobert${i:0:7}/
替换了${i:0:1}/${i:1:1}/${i:2:1}/
,它完美地工作了。 - jdias