Linux的:将1个百万个文件为基础的前缀创建的文件夹(Linux: Move 1 million

2019-07-31 14:11发布

我有一个名为“影像”充满了大约一万张图片的目录。 是的。

我想写一个shell命令将所有这些图像的重命名为以下格式:

filename.jpg
/f/i/l/filename.jpg

有什么建议?

谢谢,

Answer 1:

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*.*还是什么适合你)

编辑:增加了$之前imv ,由丹指出



Answer 2:

您可以使用,例如,sed中生成新的文件名:

$ 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要解决这个问题。



Answer 3:

你可以做到这一点作为一个bash脚本:

#!/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

不用说,你可能需要担心的空间和一个带有短名的文件。



Answer 4:

我建议短的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)


Answer 5:

任何提出的解决方案,其在外壳中使用通配符语法很可能会失败,因为你有文件的数量之多。 目前提出的解决方案,perl的一个可能是最好的。

但是,您可以轻松地适应任何的shell脚本的方法来处理任意数量的文件这样的:

ls -1 | \
while read filename
do
  # insert the loop body of your preference here, operating on "filename"
done

我仍然会用perl,但如果你是仅限于具有简单的Unix工具身边,然后像我展示应该让你有结合上述外壳的解决方案之一,一环。 这将是缓慢的,但。



文章来源: Linux: Move 1 million files into prefix-based created Folders