Я пропускаю два ответа в ответах, поэтому добавляю еще один.
Хотя это напоминает мне о добавлении еще одного стандартного ответа ...
Здесь есть две проблемы:
У меня есть каталог, содержащий около 280 000 файлов.
Большинство инструментов не так хорошо масштабируются с таким количеством файлов. Не только большинство инструментов для Linux или Windows, но и довольно много программ. И это может включать в себя вашу файловую систему. Долгосрочное решение было бы «ну, не делай этого тогда». Если у вас разные файлы, но они в разных каталогах. Если не ожидайте, что продолжите сталкиваться с проблемами в будущем.
Сказав это, давайте перейдем к вашей актуальной проблеме:
Если я использую cp или mv, то получаю ошибку «список аргументов слишком длинный»
Это вызвано расширением * оболочкой. Оболочка имеет ограниченное пространство для результата, и она заканчивается. Это означает, что любая команда с *
расширенным оболочкой, столкнется с той же проблемой. Вам нужно будет либо расширить меньше параметров одновременно, либо использовать другую команду.
Одна альтернативная команда, часто используемая, когда вы сталкиваетесь с этой проблемой - это find
. Уже есть несколько ответов, показывающих, как его использовать, поэтому я не собираюсь повторять все это. Однако я собираюсь указать на разницу между \;
и +
, так как это может иметь огромное значение для производительности и хорошо вписаться в предыдущее объяснение расширения.
find /path/to/search --name "*.txt" -exec command {} \;
Найдет все файлы по пути /to /search / и выполнит команду с ним, но заметит кавычки вокруг *
. Это кормит * для команды. Если бы мы не инкапсулировали или не экранировали его, то оболочка попыталась бы расширить его, и мы получили бы ту же ошибку.
Наконец, я хочу кое-что упомянуть о {}. Эти скобки заменяются содержимым, найденным функцией find. Если вы заканчиваете команду точкой с запятой ;
(тот, который вам нужно убежать из оболочки, следовательно, \;
в примерах), затем результаты передаются один за другим. Это означает, что вы будете выполнять 280000 команд mv. Один для каждого файла. Это может быть медленно.
В качестве альтернативы вы можете закончить с +
. Это передаст столько аргументов, сколько возможно одновременно. Если bash может обрабатывать 2000 аргументов, команда find /path -name "* filetype" -exec some_move {}+ вызовет команду some_move примерно 140 раз, каждый раз с 2000 аргументами. Это более эффективно (читай: быстрее).