У меня есть папка с 600 ГБ файлов. Я хочу автоматически скопировать первые 300 в одну папку, а остальные в другую папку. Я не уверен, как ограничить результаты с помощью ls или чем-то еще, чтобы передать его в качестве аргумента ...
платформа - это Linux ...
изменить: я хочу переместить 300 ГБ, а не первые 300 файлов. Размеры файлов произвольные, порядок не имеет значения.
Обновление: О, первые 300 ГБ, ну тогда ... это, вероятно, медленно, в зависимости от размера файла, но мне нравится упражнение :-)
filesize=0
for i in *; do
filesize=$(stat -c "%s" "$i");
(( totalsize += filesize ));
if [[ $totalsize < 322122547200 ]]; then
mv "$i" first_300/
else
mv "$i" the_rest/
fi
done
Надеюсь, с размером int нет проблем.
Если вы имеете в виду разбить их на папки по 300 файлов в каждой, возможно, вам нужно что-то вроде следующего:
folder=0
counter=0
for i in *; do
mv $i foo_$folder/
if [[ $(( counter % 10 )) -eq 0 ]]; then
(( folder++ ));
fi
(( counter++ ))
done
Хотя это может быть не так быстро, как некоторые команды поиска. Если вы просто хотите выполнить первую команду 300, вы можете использовать ту же стратегию счетчика, но использовать while $ counter -le 300.
Это способ получить почти равное распределение 300 ГБ,
Вы могли бы сделать du
основанный на поиске, чтобы найти распределение по каталогам и файлам верхнего уровня, а затем разделить их почти на две части с некоторыми пробами.
find . -maxdepth 1 -type d -exec du -sk {} \; | sort -n -k 1 > list.txt
Это даст отсортированный список KB
размеры.
Вы можете проделать трюк, например выбрать альтернативные строки в этом списке для быстрого почти равномерного распределения.
awk '{if (FNR%2==1) print $2}' list.txt > list1.txt
awk '{if (FNR%2==0) print $2}' list.txt > list2.txt
Очень грубое распределение ...
Наконец, если у вас очень неравномерный размер файлов или каталогов - довольно далеко от распределения 300 ГБ,
держись подальше от тара проблема и проделайте несколько простых проб по перемещению пары строк между двумя файлами списков.
Найдите разницу между двумя наборами (с du
) и переместите каталог / файл
это примерно половина разницы между большим списком и меньшим.
Это должно приблизить вас
Вы могли бы сделать это с найти, глава & xargs. Должно получиться так:
find ./ -type f -print0 | head -300 | xargs -0 -I mv {} /one/folder
find ./ -type f -print0 | xargs -0 -I mv {} /another/folder
ПРЕДУПРЕЖДЕНИЕ! Когда вы начинаете рассчитывать размеры файлов, вы, вероятно, ошибетесь, измеряя их байтами, в то время как большинство файловых систем выделяют дисковое пространство блоками. И этот размер блока варьируется от диска к диску, но часто кратен 512.
По сути, это означает, что у вас может быть 500 файлов по одному байту каждый, что составляет всего 500 байтов. Но файловая система, которая выделяет 2048 байт на блок, таким образом, потребует около 1 мегабайта дискового пространства. Да, это много накладных расходов.
По сути, вам следует округлить получаемые размеры файлов по размеру блока используемой файловой системы. Таким образом, вы можете измерить их более точно.
Опять же, какая разница? Если размер блока составляет 2048 байтов, то среднее количество «потерянных» байтов составит 1 КБ. С 300 файлами это будет около 300 КБ, что вам понадобится больше, чем ваш общий размер. Вы хотите скопировать 300 ГБ, но сколько это будет файлов? И используют ли два диска одну и ту же файловую систему с одинаковым размером блока?
В любом случае допустимая погрешность зависит от среднего размера файла. Если у вас много огромных файлов (музыка, изображения, двоичные файлы), погрешность будет очень маленькой. Если у вас много небольших файлов (например, сценариев, исходников и текстовых файлов), то допустимая погрешность может легко добавить еще 30 ГБ к общему размеру файла, который вы не учли ...
Итак, измерить размеры файлов непросто ...
Вы можете получить список использования файлов, вытащив размер из ls -l
или используя du
команда:
$ cd /dirwithlotsoffiles
$ du -k *
Будет напечатан список размеров файлов в килобайтах, за которым следует имя файла.
Ответ «найти» будет копировать первые 300 файлов, а не первые 300 ГБ, как я понимаю под запросом.
Вы можете попробовать tar и его многотомные варианты
Довольно грубый способ - перебрать файлы, отсортированные по размеру (ls -S), и просто переместить каждый альтернативный файл в один из подкаталогов. Как насчет этого:
#!/usr/bin/bash
dir1=path/to/dir1
dir2=path/to/dir2
a=0
for file in `ls -1S`
do
a=`expr $a + 1`
even=`expr $a%2|bc`
if [ $even -gt 0 ]
then
mv $file $dir1
else
mv $file $dir2
fi
done
~
Боюсь, вам, вероятно, придется запачкать руки написанием скриптов. Вы можете легко получить список файлов и их размер, используя команду терминала ls -l, тогда вам нужно будет написать сценарий, который просматривает этот список и копирует файлы один за другим и ведет счетчик для записи количества КБ передано пока. Каждый раз проверяйте, переместили ли мы уже 300 ГБ, если нет, переместите другой файл. Вероятно, это можно сделать примерно в 10 строках Perl или меньше.
Вы можете получить разумный результат, просто получив список имен файлов вместе с размером каждого файла. Сначала отсортируйте файлы по размеру наибольшего. Затем просто скопируйте самый большой файл в списке, который уместится в оставшемся пространстве в целевом каталоге, и удалите его из списка. Повторяйте, пока не перестанут подходить файлы.
Затем начните снова с нового целевого каталога. Повторяйте, пока список не станет пустым.