
Предположим, что есть текст (код ассемблера)
st.w av,d15
ld.w d15,av
Предположим, мы хотим сопоставить его с grep. Мы можем использовать этот шаблон:
pattern=\
'\s+st.w\s+av,.*'\
'\s+ld.w\s+.*,av'
Примечание: мы используем .*
для сопоставления имен регистров. В будущем эти имена регистров могут измениться.
Предположим, мы хотим использовать специальное регулярное выражение для имен регистров. Добавляем специальное @reg
ключевое слово:
pattern=\
'\s+st.w\s+av,@reg'\
'\s+ld.w\s+@reg,av'
Затем мы добавляем предварительную функцию для шаблона grep, в которой мы заменяем все специальные ключевые слова на реальные шаблоны регулярных выражений:
preprocess_pattern () {
local result=$1
# Replace @reg to exact regex pattern [a..d][0..15].
result=${result//'@reg'/'[a-d](1[0-5]|[0-9])'}
# Add other replacements (if need).
#result=${result//''/''}
echo "$result"
}
Затем мы вызываем preprocess_pattern()
перед выполнением grep
:
pattern="$(preprocess_pattern $pattern)"
if ! grep -Pzo $pattern code.asm > /dev/null
then
echo "grep #$i failed (pattern: "$pattern")"
((++failed))
fi
Это работает, но мы хотим большего.
Мы хотим добавить @preg
, что этопредыдущий регистр.
pattern=\
'\s+st.w\s+av,@reg'\
'\s+ld.w\s+@preg,av'
Теперь вопрос: где (и как) добавить логику, которая после каждого появления@reg
сохраняетсовпавшее значение (в нашем случае d15
) в специальном стеке/буфере и после каждого появления@preg
извлекаетсовпавшее значение из стека/буфера и сравнивает это значение со значением @preg
?
Другими словами: как написать шаблон для сопоставления данных сконтекстно-зависимыйэлементы? Возможно ли это вообще с grep?
Если да (т.е. возможно), то как это описать?чувствительность к контекстув узоре?
Если нет (т.е. невозможно), то как еще решить эту задачу?
решение1
То, чего вы пытаетесь достичь, может быть достигнуто с помощью grep + regex, но это будет сложно. Для вашей задачи нужен полноценный скрипт или программа на каком-то языке.
Следующие особенности различных команд могут оказаться полезными
- Контекст Grep: единственный контекст, который предоставляет grep, — это количество строк
before
иafter
совпавшая строка [-A
,-B
,-C
(комбинация предыдущих двух)] - Awk и Sed: с их помощью можно искать текст по двум шаблонам.
Но опять же, это будет сложно. Насколько я понимаю, вы пытаетесь написать какой-то парсер, поэтому вам следует изучить и попробовать использовать инструмент записи, прежде чем переходить к написанию сложных команд.