Я пытаюсь разобрать стандартный diff некоторых файлов sql, чтобы вернуть только разделы удаления. Я использую grep с контекстом после (-A), который почти работает (только потому, что я знаю, что разделы удаления будут очень короткими). например
diff $$_$1.sql $$_$2.sql|egrep -A3 "[01234567889][01234567889]d[01234567889][0123456789]"
Я думаю, что с AWK я мог бы сказать, что он начинается с (указанное выше регулярное выражение) и останавливается на первой строке, начинающейся с цифры, или первой строке, заканчивающейся на -
Я немного поигрался, но не могу найти правильный синтаксис для этого. Можно ли это сделать с помощью AWK? или есть другой инструмент, который мне следует использовать?
Я был бы склонен попробовать сделать это с помощью унифицированного diff и простого grep:
diff -u a.sql b.sql | grep -v '^\+' | rediff
В rediff
собирается попытаться исправить смещения после того, как вы исказили различия ... он не будет работать во всех обстоятельствах, но это лучшая надежда, которая у вас есть, чтобы сохранить действительный diff.
Я думаю, что с AWK я мог бы сказать, что он начинается с (указанное выше регулярное выражение) и останавливается на первой строке, начинающейся с цифры, или первой строке, заканчивающейся на -
Приведите пример, если это не то, что вам нужно:
sed -n '/[0-9][0-9]d[0-9][0-9]/,/^[0-9]\|--$/p'
РЕДАКТИРОВАТЬ
Хотя вы приняли мой ответ, но я все же хочу отредактировать свое сообщение, чтобы поделиться с вами регулярным выражением, которое может помочь вам полностью решить вашу проблему. sed
позволяет вам исключая совпадающие строки с участием b
- команда ветки:
sed -n '/[0-9][0-9]d[0-9][0-9]/,/^[0-9]\|--$/ { /^[0-9]/b; p }'
но с этим регулярным выражением sed
также удалите REGEX1. Так, Смотреть вперед появляется в моей голове:
sed -n '/[0-9][0-9]d[0-9][0-9]/,/^[0-9]\|--$/ { /^[0-9](?:(?![0-9]d[0-9][0-9]).*)$/b; p }'
но это не работает, потому что sed
, awk
, grep
использует аромат POSIX RE, который не поддерживает негативный взгляд вперед. Вам следует попробовать Python, Perl, Ruby, ...
diff ... | awk '/start-mark/ {flag = 1} /end-mark/ {flag = 0} flag'
Ваше регулярное выражение, вероятно, можно упростить, чтобы [0-9]
(и т.д.)
В flag = 0
можно изменить на exit
если вы хотите напечатать только первый совпадающий диапазон строк.