Я пытаюсь запустить следующую команду:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +
Это возвращает ошибку:
find: missing argument to -exec
Я не вижу, что не так с этой командой, так как она соответствует странице руководства:
-exec команда {} +
Этот вариант опции -exec запускает указанную команду для выбранных файлов, но командная строка создается путем добавления каждого выбранного имени файла в конце; общее количество вызовов команды будет намного меньше, чем количество совпадающих файлов. Командная строка строится почти так же, как xargs создает свои командные строки. В команде допускается только один экземпляр «{}». Команда выполняется в начальном каталоге.
Я также попробовал:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '{}' +
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '{}' +
find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '{}' +
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
+
в конце?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
find
. Хотя-exec cmd {} +
вариант POSIX и был доступен с 80-х годов, GNU find только добавила его (относительно) недавно (2005). Чтоfind --version
тебе сказать?-exec {} +
был добавлен в 4.2.12 в 2005 году. В более ранних версиях GNU вы можете использовать (не POSIX),-print0 | xargs -r0
чтобы получить нечто подобное.4.1
с 1994 года.-name
аргументы модели должны быть указаны:-name "*.c" -o -name "*.h"
. Это правда, хотя это не связано с-exec
ошибкой. Вы заметите, что все остальные ответы помещают символы подстановки в кавычки, хотя об этом упоминает только Жиль. … (Продолжение)-name "*.[ch]"
без объяснения причин. Это дает преимущества упрощения командной строки и, в частности, устранения-o
. Найти выражения с участием-o
трудно понять правильно. Твое неправильно; если ваша команда исправлена, чтобы не выдавать ошибку (как в ответе Жиля), она будет выполнятьсяgrep
только для.h
файлов. Тебе нужно сделать'(' -name '*.c' -o -name '*.h' ')'
.Ответы:
Вам нужно удалить одинарные кавычки, которые вы используете вокруг
{}
. Команду можно упростить так:Если вы используете архаичную версию поиска GNU, это все равно должно работать:
источник
{}
не имеют конкретного значения для оболочки.«Отсутствует аргумент
-exec
» обычно означает, что аргумент -exec
отсутствует его терминатор. Ограничитель должен быть либо аргумент , содержащий только символ;
(который должен быть в кавычках в команде оболочки, так что это , как правило , письменное\;
или';'
) или две последовательные аргументы , содержащие{}
и+
.Stephane Chazelas определил, что вы используете более старую версию GNU find, которая не поддерживает
-exec … {} +
только-exec {} \;
. Хотя GNU был поздним последователем-exec … {} +
, я рекомендую вам приобрести менее антикварный набор инструментов (например, Cygwin , который включает в себя git и многое другое, или GNUwin32 , в котором отсутствует git, но нет попытки плохого сотрудника). -все-использую-linux-но-мы-навязываем окна, которые дает Cygwin). Эта функция была добавлена в версии 4.2.12 более 9 лет назад (это была последняя идентифицированная функция, обеспечивающаяfind
совместимость с GNU POSIX).Если вы хотите придерживаться более старой находки GNU, вы можете использовать
-print0
с,xargs -0
чтобы получить похожую функциональность: групповое выполнение команд, поддержка произвольных имен файлов.Всегда указывайте символы подстановки в
find
командной строке. В противном случае, если вы запустите эту команду из каталога, содержащего.c
файлы, не заключенный в кавычки*.c
будет расширен до списка.c
файлов в текущем каталоге.Добавление
/dev/null
вgrep
командную строку - хитрость, гарантирующая, что grep всегда будет печатать имя файла, даже еслиfind
будет найдено единственное совпадение. В GNU find другой способ - передать опцию-H
.источник
Если команда, такая как
возвращает ошибку
вероятная причина - слишком старый GNU,
find
который не поддерживает синтаксис-exec mycommand {} +
. В этом случае замена с низкой производительностью - это запуск,-exec mycommand {} \;
который будет запускатьmycommand
один раз для каждой найденной цели вместо того, чтобы собирать несколько целей и запускатьmycommand
только один раз.Однако GNU
find
не поддерживает, например,потому что GNU
find
поддерживает только буквальную комбинацию,{} +
а не более общую{} additional parameters +
. Обратите внимание, что между фигурными скобками и+
персонажем не должно быть ничего . Если вы попробуете это, вы получите ту же ошибку:Обходной путь должен использовать синтаксис,
{} additional parameters \;
который работает, но выполнит команду один раз для каждой найденной цели. Если вам нужна большая производительность с GNU,find
вы должны написать скрипт-обертку, который может добавлять дополнительные параметры к указанным аргументам. Что-то вродедолжно быть достаточно хорошо. Или, если вы не хотите создавать временный файл, вы можете использовать однострочник для изменения порядка параметров следующим образом:
который выполнит
mycommand {list of ttf files} extra arguments
. Обратите внимание, что вам может потребоваться двойная экранирование специальных символов для bash после-c
флага.источник
find
, а правильным поведением, указанным в POSIX .find
у вас, вероятно, есть GNUcp
. В этом случае вы можетеfind ... -exec cp --target-directory ~/.fonts {} +
оставить{}
в конце строки выполнения.find . -type f -perm 0777 -exec chmod 644 {}\;
получил ошибку
find: missing argument to ``-exec'
.Добавляем пространство между
{}
и\
исправляем:find . -type f -perm 0777 -print -exec chmod 644 {} \;
источник
find
команде в рассматриваемом вопросе.+
формы-exec
опцииfind
. Этот ответ исправляет проблему, которой нет у пользователя, задающего вопрос.У меня была моя доля головной боли с синтаксисом exec в прошлом. большинство дней я предпочитаю более приятный синтаксис bash:
У него есть некоторые ограничения, когда вы хотите рассматривать файлы как группу, так как каждый оценивается последовательно, но вы можете передать результаты в другом месте просто отлично
источник
find … -exec … \;
, поэтому нет причин использовать это, даже если вы знаете, что ваши имена файлов ручные.exec
была слишком большой головной болью для 5 минут, которые я хотел потратить на это. Мои имена файлов были ручными, и это решило мою проблему :)