約100万の画像で埋められた「画像」というディレクトリがあります。うんLinux:100万ファイルをプレフィックスベースの作成済みフォルダに移動
私は、次の形式にそれらの画像のすべての名前を変更するシェルコマンドを書きたい:
元:filename.jpg
新しい:/f/i/l/filename.jpg
任意の提案ですか?
おかげで、
ダン
約100万の画像で埋められた「画像」というディレクトリがあります。うんLinux:100万ファイルをプレフィックスベースの作成済みフォルダに移動
私は、次の形式にそれらの画像のすべての名前を変更するシェルコマンドを書きたい:
元: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*.*
または何をフィット):ダン
mv
ため
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を使用したいだけの場合があります。
#!/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
を使用することができますが。
私は短いpythonスクリプトを提案します。ほとんどのシェルツールはその多くの入力を嫌うでしょう(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)
ありがとう、すばらしい解決策のようです。私は試してみる前に、ファイルを私の新しいサーバに転送するのを待つ必要があります(ETA 50時間LOL) – Dan
あなたは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
言うまでもないを言って、あなたは、スペースと短い名前のファイルを心配する必要がある場合があります。
とてもいい解決策です、ありがとうございます – Dan
シェルでワイルドカード構文を使用する提案された解決策のいずれかが、あなたが持っているファイルの数のせいで失敗する可能性があります。現在提案されている解決法のうち、perlがおそらく最高です。
しかし、あなたは簡単にこのように任意の数のファイルを扱うためにシェルスクリプトのいずれかの方法を適応させることができます。
ls -1 | \
while read filename
do
# insert the loop body of your preference here, operating on "filename"
done
私はまだPerlを使用しますが、あなただけの単純なUNIXツールを有することに限定している場合このシェルソリューションの1つを、私が示したようなループと組み合わせると、そこにあなたがいるはずです。しかし、それは遅くなるでしょう。
100万画像ええ?それはたくさんのポルノです! –