Попытка импортировать более 53 800 отдельных файлов (сообщений) с помощью сборщика POP Gmail.
Gmail по понятным причинам отказывается, выдавая ошибку: «Слишком много сообщений для загрузки. Слишком много сообщений на другом сервере».
Рассматриваемая папка выглядит примерно так:
/usr/home/customer/Maildir/cur/1203672790.V57I586f04M867101.mail.net:2,S
/usr/home/customer/Maildir/cur/1203676329.V57I586f22M520117.mail.net:2,S
/usr/home/customer/Maildir/cur/1203677194.V57I586f26M688004.mail.net:2,S
/usr/home/customer/Maildir/cur/1203679158.V57I586f2bM182864.mail.net:2,S
/usr/home/customer/Maildir/cur/1203680493.V57I586f33M740378.mail.net:2,S
/usr/home/customer/Maildir/cur/1203685837.V57I586f0bM835200.mail.net:2,S
/usr/home/customer/Maildir/cur/1203687920.V57I586f65M995884.mail.net:2,S
...
Используя оболочку (tcsh, sh и т. Д. Во FreeBSD), какую однострочную команду я могу ввести, чтобы разделить этот каталог, полный файлов, на отдельные папки, чтобы Gmail видел только 1000 сообщений за раз? Что-то с find или ls | xargs mv может быть. Что бы ни было быстрее.
Желаемый выходной каталог теперь будет выглядеть примерно так:
/usr/home/customer/Maildir/cur/1203672790.V57I586f04M867101.mail.net:2,S
/usr/home/customer/Maildir/cur/1203676329.V57I586f22M520117.mail.net:2,S
...
/usr/home/customer/set1/ (contains messages 1-1000)
/usr/home/customer/set2/ (contains messages 1001-2000)
/usr/home/customer/set3/ (etc.)
Это не однострочник, но вы можете копировать такие фрагменты (в csh):
foreach file (`ls | head -n 1000`)
mv $file /tmp/new/dir
end
Я не уверен на 100%, что pipe будет работать с тем количеством файлов, которое у вас есть, но попробовать стоит. Кроме того, с помощью этой команды вы можете выполнять 500 за раз, просто измените это значение с 1000 на 500.
count=target=0;
find srcdir/ -type f |
while read file; do
count=$((count+1));
target=$((count/10000));
[ -d $target ] || mkdir $target
echo mv "$file" $target; #remove the 'echo' if you like what you see
done
свернуто в одну строку (и с удаленной защитой 'echo'):
count=target=0; find srcdir/ -type f | while read file; do count=$((count+1)); target=$((count/10000)); [ -d $target ] || mkdir $target; mv "$file" $target; done
Это не самый быстрый, но чистый. это решение позволяет избежать синтаксического анализа вывода ls http://mywiki.wooledge.org/ParsingLs и цитирует ссылки на «$ file», иначе файлы с ненормальными именами (как это часто бывает в файлах Maildir) нарушат код. Например, если в каком-либо из файлов есть пробелы или точки с запятой, то ссылка на $ file без кавычек не приведет вас далеко (в большинстве случаев)
Подробнее о цитировании: http://mywiki.wooledge.org/Quotes и http://wiki.bash-hackers.org/syntax/words