Другой ответ , предлагающий - no-messages
/ -s
, , более подходит для вашей проблемы, но следующее также будет работать для команд у которых нет «тихой» опции.
Чтобы перенаправить ошибки из простой команды , вы должны поместить перенаправление с этой командой, т.е. в той же позиции в конвейере:
if [ "$(grep -v '^;\|^\[' "path_to_file/config.ini" 2>/dev/null | \
grep -c '\\some_word')" -ge 1 ] \
Первый grep
- это тот, который генерирует сообщение «Нет такого файла или каталога», поэтому его нужно перенаправить.
Если несколько частей конвейера могут генерировать ошибки, вы можете поместить весь конвейер в группу с одним перенаправлением после него:
if [ "$( ( grep -v '^;\|^\[' "path_to_file/config.ini" | \
grep -v -f "path_to_file/ignored_patterns" | \
grep -c '\\some_word' ) 2>/dev/null )" -ge 1 ] \
Вы можете перенаправить всю конструкцию if
, поместив перенаправление после закрытия fi
:
if [ "$(grep -v '^;\|^\[' "path_to_file/config.ini" | \
grep -c '\\some_word')" -ge 1 ] \
...
else
...
fi 2>/dev/null
Это перенаправит ошибки всех команд (обе тест- и консеквент- ) внутри этого блока.
Есть фраза, которую следует запомнить: "Регулярные выражения не умеют считать".
В данном случае это имеет значение, потому что многие "простые" инструменты unix основаны на регулярных выражениях. Подсчет здесь заключается в подсчете открытых и закрытых круглых скобок ("round brackets"), которые могут быть использованы внутри аргументов Test_Macro.
Если вызовы Test_Macro никогда не содержат вложенных круглых скобок, то есть простой трюк. Сначала замените каждый символ )
на новую строку, и наоборот. Затем удалите все строки, не содержащие Test_Macro, и удалите все до Test_Macro. В этот момент часть обработанного файла File2.txt будет выглядеть так
Test_Macro(abc, def, " string1 string2 test string",) "test string2 ",) 123456
Теперь нам нужно преобразовать )
обратно. На этом этапе у вас есть несколько вариантов. Я предпочитаю использовать sed, чтобы избавиться от лишних пробелов. Нам также нужно добавить обратно )
и, возможно, ;
Сложив это вместе, мы имеем
find . -type f | while read -r fn
do
< "$fn" tr ')\n' '\n)' | sed -n 's/.*Test_Macro(/Test_Macro(/p' | \
sed 's/) */ /g;s/$/);/'
done
Если есть вероятность, что аргументы Test_Macro включают вложенные круглые скобки, то вам нужно достать значительно больше оружия, поскольку вам нужно разобрать входные данные, а не просто сопоставить их с образцом. (Теоретически, если вы можете ограничить уровень вложенности, то вы можете использовать шаблонизацию, но на практике это очень быстро усложняется, и вам следует отказаться от такого подхода). Существуют каркасы парсеров для таких языков, как python, или вы можете создавать инструменты на основе таких инструментов, как lex.