Какой недостающий аргумент для -exec?

15

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

Это команда, которую я использую:

find /path/to/directory/username/ -mtime +30 -exec mv "{}" /path/to/archive/username/ \;

Я предложил модифицированную версию этого , чтобы ответить на вопрос о том, спросить убунт, другой пользователь редактирует код , чтобы изменить конец строки \;для , +как это быстрее (и правильнее?). Посмотреть здесь

Тем не менее, использование +таким образом работает, если -execкоманда, ls -lhно не в фактической команде, которую я использую. Если я попробую это сделать, +я получу сообщение об ошибке:

find: missing argument to '-exec'

Я не понимаю, почему он так себя ведет, или какой будет правильная команда. Пожалуйста, не просто публикуйте исправление команды, я хотел бы понять, а не просто слепо следовать предложению.

Arronical
источник
Вы имеете в виду этот ответ ? Это может объяснить почему
Уилф
Спасибо @Wilf Я обновил, чтобы показать, на какой ответ произошло редактирование. Ссылка, которую вы предоставили, имеет дополнительную ссылку, которая объясняет это так, как мой мозг может справиться.
Arronical
Спасибо @souravc блестяще циклически, этот вопрос от пользователя, который отредактировал мою команду! Наконец, я получаю, что он +предоставляет несколько аргументов для одной и той же команды, но mvне может справиться с этим!
Arronical
@ Arronical mv can, посмотри мой ответ ^^
хаос

Ответы:

19

Пользователь в этом посте может сказать, что +знак в конце -execкоманды быстрее, но не почему.

Предположим, findкоманда вернула следующие файлы:

/path/to/file1
/path/to/file2
/path/to/file3

Обычная -execкоманда ( -exec command {} \;) запускается один раз для каждого соответствующего файла. Например:

find ... -exec mv {} /target/ \;

Выполняет:

mv /path/to/file1 /target/
mv /path/to/file2 /target/
mv /path/to/file3 /target/

Если вы используете +знак ( -exec command {} +), команда собирается путем добавления нескольких совпадающих файлов в конце команды. Например:

find ... -exec mv -t /target/ {} +

Выполняет:

mv -t /target/ /path/to/file1 /path/to/file2 /path/to/file3

Чтобы +правильно использовать флаг, аргумент для обработки должен находиться в конце команды, а не в середине. Вот почему findТроу missing argument to '-exec'в вашем примере; это пропускает закрытие {}.

хаос
источник
Я всегда задавался вопросом, почему find -execтребуется {}последний аргумент, когда используется с +. Кто-нибудь знает, почему было принято это проектное решение, вместо того, чтобы позволить конструкциям, подобным командной строке OP, работать?
Питер Кордес
11

Пользователь объяснил их редактирование ....

'+' терминатор exec быстрее чем '\;'  см. /ubuntu/558817/what-is-the-difference-between-using-and-in-exec-command;  и создание файла резервной копии из исходного файла это хорошая идея

... используя эту ссылку . Я думаю, что в основном вместо использования нескольких команд он отправляет все имена файлов одному экземпляру команды, чтобы ускорить процесс. Вот пример отсюда :

Использование -exec с точкой с запятой ( find . -exec ls '{}' \;), выполнит

ls file1
ls file2
ls file3

Но если вместо этого использовать знак плюс ( find . -exec ls '{}' \+), все имена файлов будут переданы в качестве аргументов одной команде:

ls file1 file2 file3

Есть и другие формы, доступные с использованием ;и +также ( отсюда :)

Поэтому синтаксис следующего примера разрешен для команды find:

find . -exec echo {} \;
find . -exec echo {} ';'
find . -exec echo {} ";"
find . -exec echo {} \+
find . -exec echo {} +

ОДНАКО, я не уверен, что это все равно будет работать с командой перемещения, так как это синтаксис mv [OPTION]... SOURCE DEST, если только не используется -tопция или подобное. Однако он должен работать lsбез лишних опций и т. Д., Поскольку они могут понять, когда задано несколько имен файлов. +Также нужно экранировать (то есть \+)

Уилф
источник
Оба отличных ответа, но я должен отдать должное хаосу за то, что он был чуть-чуть быстрее и объяснил mv -t, хотя оба + 1!
Arronical