2

Я работаю на сервере CentOS, и мне нужно перемещаться и собирать миллионы файлов. Я пробовал много воплощений чего-то подобного ниже, но все они терпят неудачу со слишком длинной ошибкой списка аргументов.

команда:

find ./ -iname out.* -type f -exec mv {} /home/user/trash
find ./paramsFile.* -exec cat > parameters.txt 

ошибка:

-bash: /usr/bin/find: Argument list too long
-bash: /bin/cat: Argument list too long

или же

echo ./out.* | xargs -I '{}' mv /home/user/trash
(echo ./paramsFile.* | xargs cat) > parameters.txt  

ошибка:

xargs: argument line too long
xargs: argument line too long              

Вторая команда также никогда не заканчивалась. Я слышал кое-что о глобусе, но не уверен, что полностью понимаю. Любые намеки или предложения приветствуются!

3 ответа3

4

У вас есть несколько ошибок. Вы должны избежать * подстановки. Вы должны поместить {} кавычки (для безопасности имени файла), и вы должны завершить -exec \; ,

find ./ -iname out.\* -type f -exec mv "{}" /home/user/trash \;
find -name ./paramsFile.\* -exec cat "{}" >> parameters.txt \;

Проблема здесь в том, что * соответствует всем файлам в вашем каталоге, таким образом, выдает ошибку. Если команда find находит файлы вместо глобализации оболочки, xargs получает отдельные имена файлов, которые он может использовать для построения строк правильной длины.

1

Попробуй это:

find . -iname 'out.*' -type f -exec mv '{}' /home/user/trash \;
find . -name 'paramsFile.*' -print0 | xargs -0 cat >> parameters.txt

>> должен гарантировать, что множественные вызовы cat (если у вас действительно огромное количество файлов) выводятся в один и тот же файл, не перезаписывая результат предыдущих вызовов. Кроме того, убедитесь, что parameters.txt начинается пустым (или сначала удалите его).

0

В данный момент у меня нет коробки, чтобы дать очень хороший (то есть проверенный) ответ, но я думаю, что это хорошее применение для parallel.

Если я правильно понимаю, ваша команда

find ./ -iname out.* -type f -exec mv "{}" /home/user/trash

делает одну огромную команду:

mv out.1 out.2 out.3 out.4 ... out.10100942 /home/user/trash

Вместо этого что-то вроде

find ./ -iname out.* -type f | parallel mv "{}" /home/user/trash

выполнит миллионы меньших команд:

mv out.1 /home/user/trash
mv out.2 /home/user/trash
...

Возможно, вы захотите взглянуть на некоторые параметры parallel , в частности, -j и -i чтобы избежать неожиданной перегрузки вашего сервера.

PS. Следуйте советам @ Bernhard, всякий раз, когда вы используете переменную оболочки, особенно для пользовательского ввода, заключайте в кавычки! Не "{}" не {} .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .