Bash: как использовать «find» в сочетании с «-exec grep» для поиска пустой пары фигурных скобок

Я знаю, что есть другие способы сделать это, но мне любопытно, терпите меня.

Я хотел бы найти в дереве каталогов файлы манифеста 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 05.04.2023 12:52

@anubhava В нем говорится: «найти: с -exec ... + поддерживается только один экземпляр {}» ...

Johan Bezem 05.04.2023 13:27

@ General: я не знаю, кто проголосовал за закрытие моего вопроса, потому что «он нарушает правила переполнения стека», но было бы полезно добавить комментарий, объясняющий, что, по вашему мнению, не так.

Johan Bezem 05.04.2023 13:34
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете выйти из второй скобки, но вам нужно опустить -F:

find . -type f -name *.json -exec grep -Hm 1 '"submodules": {\}' {} \;

Кроме того, использование + вместо \; может запускать grep для многих файлов одновременно, т. е. может быть быстрее.

Извините, но, похоже, это не работает, так как экранирование для второй фигурной скобки является экранированием оболочки и не работает в строках с одинарными кавычками. Ты пробовал? Это не работает для меня.

Johan Bezem 05.04.2023 13:06

Хорошо, я нашел причину: я не использовал -F.

choroba 05.04.2023 14:44
Ответ принят как подходящий

Решение с использованием 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. Я не думал об этом! Ваше второе предложение также будет работать, но избегание комбинации {} в строке поиска путем разделения на несколько команд — это не то, что я искал.

Johan Bezem 05.04.2023 13:20

Другие вопросы по теме