Я знаю, что есть другие способы сделать это, но мне любопытно, терпите меня.
Я хотел бы найти в дереве каталогов файлы манифеста JSON, содержащие точную строку: "submodules": {}
, результат конвейера Jenkins.
Я попробовал несколько комбинаций и нашел ту, которая находит все нужные мне локации:
find . -type f -name *.json -exec grep -FHm 1 '"submodules": {' {} \;
Это работает, поэтому моя проблема решена.
Но теперь мне просто любопытно: я знаю, что {}
имеет особое значение для команды поиска. Как я могу переписать эту команду поиска для поиска "submodules": {}
? Интуитивной первой попыткой будет:
find . -type f -name *.json -exec grep -FHm 1 '"submodules": {}' {} \;
Но даже несмотря на то, что оболочка не затрагивает строку поиска из-за одинарных кавычек, у команды find такого ограничения нет, и команда ничего не находит.
Я попробовал несколько способов цитирования и экранирования, но не смог найти работающую комбинацию. Любой?
@anubhava В нем говорится: «найти: с -exec ... + поддерживается только один экземпляр {}» ...
@ General: я не знаю, кто проголосовал за закрытие моего вопроса, потому что «он нарушает правила переполнения стека», но было бы полезно добавить комментарий, объясняющий, что, по вашему мнению, не так.
Вы можете выйти из второй скобки, но вам нужно опустить -F
:
find . -type f -name *.json -exec grep -Hm 1 '"submodules": {\}' {} \;
Кроме того, использование +
вместо \;
может запускать grep
для многих файлов одновременно, т. е. может быть быстрее.
Извините, но, похоже, это не работает, так как экранирование для второй фигурной скобки является экранированием оболочки и не работает в строках с одинарными кавычками. Ты пробовал? Это не работает для меня.
Хорошо, я нашел причину: я не использовал -F
.
Решение с использованием egrep
/grep -E
:
find . -type f -name '*.json' -exec grep -EHm 1 '"submodules": \{\}' {} \;
find . -type f -name '*.json' -exec egrep -Hm 1 '"submodules": \{\}' {} \;
Используя простой grep (без -F
), добавив избыточный класс символов:
find . -type f -name '*.json' -exec grep -Hm 1 '"submodules": [{]}' {} \;
Вы также можете создать файл для запуска grep, например. grep.sh
:
cat > grep.sh <<SH
#!/bin/sh
grep -FHm 1 '"submodules": {}' "$@"
SH
chmod +x grep.sh
затем выполните файл сценария через find:
find . -type f -name '*.json' -exec ./grep.sh {} \;
Хороший, я не подумал об этом. Вы позволяете grep предположить, что он получает регулярное выражение в качестве входных данных, поэтому вы можете избежать фигурных скобок, которые grep затем удаляет для поиска, избегая буквальной комбинации {}
, которая вызвала бы find
. Я не думал об этом! Ваше второе предложение также будет работать, но избегание комбинации {}
в строке поиска путем разделения на несколько команд — это не то, что я искал.
Это работает, если вы замените
\;
на+