Мой желаемый результат следующий: рекурсивно искать в каталоге заданную строку во всех найденных файлах. Следующая команда — мой обычный порт вызова:
find ./ | xargs grep -ns 'foobar'
Однако, когда foobar
есть кавычки, команда не выполняется и выдает мне >
приглашение в оболочке. Конкретная команда, вызывающая проблему, следующая:
find ./ | xargs grep -ns 'add_action(\'save_post\','
Я пытался экранировать кавычки обратными косыми чертами, но безуспешно. Как правильно это сделать?
решение1
Одинарные кавычки завершаются одинарными кавычками; все остальные символы между ними сохраняются точно такими же, как есть, включая обратные косые черты. Таким образом, нет способа вставить одинарную кавычку между одинарными кавычками. (Но выможетзавершите одинарные кавычки, экранируйте одинарную кавычку и начните новый набор одинарных кавычек, как в 'Single quotes aren'\''t ever really embedded in single quotes.'
)
Предположение:Избегайте find+xargs, когда grep -r pattern .
можно рекурсивно выполнить grep в текущем каталоге.
Приведенные ниже команды имеют эквивалентное поведение:
grep -rns "add_action('save_post'," .
grep -rns 'add_action('\'save_post\', .
Последняя команда интерпретируется как:
'add_action('
->add_action(
\'
->'
save_post
->save_post
\'
->'
,
->,
Объединяя эти части, grep
команда получает аргумент add_action('save_post',
.
решение2
xargs
ожидает аргументы, закавыченные каким-то странным образом, что find
не производит. Никогда не используйте xargs
в сочетании с find
, если только вы не уверены, что имена ваших файлов не содержат \"'
пробелов.
Вместо использования xargs
давайте find
напрямую вызовем программу, которую вы хотите запустить.
find . -exec grep -ns 'add_action('\''save_post'\'',' {} +
С помощью exec … {} +
программа вызывается один раз для многих файлов одновременно, как и с xargs
. Некоторые старые версии find
не поддерживают +
here¹, тогда вместо этого вам придется использовать ;
, который вызывается grep
один раз для каждого файла.
В качестве альтернативы вы можете использовать find … -print0 | xargs -0
, если ваши утилиты поддерживают это¹. Опция -print0
указывает find
выдавать имена, разделенные нулевым байтом, и -0
указывает xargs
ожидать ввода, разделенного нулем, и не выполнять никакой интерпретации кавычек.
Обратите внимание на кавычки выше: между одинарными кавычками все символы интерпретируются буквально, за исключением того, что '
обозначает конец буквальной строки. Так что '\''
это фактически способ поместить буквальную одинарную кавычку внутрь строки в одинарных кавычках; формально это « '
конечная кавычка, \
буквальная '
одинарная кавычка, '
начальная кавычка».
В особом случае grep
, если ваша реализация поддерживает это¹, вы можете обойтись без него find
и использовать grep -r
для рекурсивного поиска внутри каталога:
grep -r 'add_action('\''save_post'\'',' .
¹ Linux, Cygwin, FreeBSD и OSX поддерживают эти функции.
решение3
grep "add_action('save_post'," ./* -R
Вы можете рекурсивно выполнить grep всех файлов в текущем каталоге с помощью
-R
опции.Строку поиска можно заключить в
"
.