Вы можете добавить параметр загрузки к параметру по умолчанию, используемому вашим загрузчиком, добавив его к значению GRUB_CMDLINE_LINUX_DEFAULT
в /etc/default/grub
. После этого запустите sudo update-grub
, чтобы обновить конфигурацию.
Поскольку вы не используете find
ни для чего другого, кроме обхода дерева каталогов, я предлагаю вместо этого использовать для этого непосредственно оболочку. См. варианты для zsh
и bash
ниже.
Использование оболочки zsh
mv./**/*(-.D[1,1000]) /path/to/collection1 # move first 1000 files
mv./**/*(-.D[1,1000]) /path/to/collection2 # move next 1000 files
Подстановочный шаблон ./**/*(-.D[1,1000])
будет соответствовать всем обычным файлам (или символическим ссылкам на такие файлы )в текущем каталоге или под ним, а затем вернет 1000 первых из них. -.
ограничивает поиск обычными файлами или символическими ссылками на них,в то время как D
действует как dotglob
вbash
(соответствует скрытым именам ).
Предполагается, что сгенерированная команда не станет слишком большой из-за расширения шаблона подстановки при вызове mv
.
Вышеописанное весьма неэффективно, так как будет расширять глобус для каждой коллекции. Поэтому вы можете захотеть сохранить пути в массиве, а затем переместить фрагменты этого:
pathnames=(./**/*(-.D) )
mv $pathnames[1,1000] /path/to/collection1
mv $pathnames[1001,2000] /path/to/collection2
Для рандомизации массива pathnames
при его создании (вы упомянули о желании переместить случайные файлы):
pathnames=(./**/*(-.Doe['REPLY=$RANDOM']) )
Вы могли бы сделать то же самое в bash
(, за исключением того, что вы не можете легко перетасовать результат совпадения glob в bash
, за исключением возможной передачи результатов через shuf
, поэтому я пропущу этот бит):
shopt -s globstar dotglob nullglob
pathnames=()
for pathname in./**/*; do
[[ -f $pathname ]] && pathnames+=( "$pathname" )
done
mv "${pathnames[@]:0:1000}" /path/to/collection1
mv "${pathnames[@]:1000:1000}" /path/to/collection2
mv "${pathnames[@]:2000:1000}" /path/to/collection3
Я думаю, это невозможно напрямую с помощью find, но вы можете использовать канал с головой и xargs, например:
find... | head -1000 | xargs -i mv "{} /path/to/collection1"
Это перемещает первые 1000 файлов в коллекцию1.
Я не думаю, что это можно сделать, используя только find
. Вы можете использовать что-то вроде:
find [... your parameters...] -print0 | head -z -1000 | xargs -0 mv -t /path/to/collection
-print0
, -z
и -0
работают вместе, чтобы убедиться, что все работает даже с переводом строки в именах файлов.
Вы можете реализовать новые тесты для find
, используя-exec
:
seq 1 1000 |
find. -exec read \; -exec mv {} /path/to/collection1 +
переместит первые 1000 найденных файлов в /path/to/collection1
.
Это работает следующим образом:
seq 1 1000
выводит 1000 строк, переданных в find
; -exec read
считывает строку, терпит неудачу, если канал закрыт (, когда выход seq
исчерпан ); -exec
завершается успешно, -exec mv...
выполняет перемещение. -exec... +
работает так, как вы ожидаете.:read
будет запускаться один раз за итерацию, но find
будет накапливать совпадающие файлы и вызывать mv
как можно меньше раз.
Это основано на том факте, чтоfind
's -exec
завершается успешно или неудачно в зависимости от состояния выхода выполняемой команды :, когда read
завершается успешно, find
продолжает обработку действий, указанных выше (, поскольку оператор по умолчанию — «и» ), и когда он терпит неудачу, find
останавливается.
Если ваш find
поддерживает действие -quit
, вы можете использовать его для повышения эффективности:
seq 1 1000 |
find. \( -exec read \; -o -quit \) -exec mv {} /path/to/collection1 +
Без этого find
будет проверять каждый отдельный файл, даже если он сохранит только 1000 для mv
.
Я предполагаю, что read
доступен как внешняя команда и реализует спецификацию POSIX дляread
; если это не так, вместо этого можно использовать sh -c read
. В обоих случаях find
запускает отдельный процесс для каждого проверяемого файла.
Ответ Стивенса 264963, вероятно, лучше всего подходит для моего случая использования -, но есть простой обходной путь для случая использования -в этом вопросе с помощью только find и head:
find. [checks] -print -exec... | head
-print
будет оцениваться перед-exec
(По крайней мере, в CentOS 8 ), и канал к голове приведет к выходу find
, когда head
закроет канал.