Регулярное выражение для совпадения только с количеством символов X от конца строки - PullRequest
8 голосов
/ 15 марта 2012

Ниже вы увидите небольшой отрывок совпадений из строки 'octeon' в дампе памяти 32b от проприетарного устройства маршрутизации.Как вы можете видеть, он содержит несколько скорректированных ASCII, простирающихся до 16 символов от конца строки, затем четыре 32-битных слова (конечно, по 8 символов каждое), затем смещение адреса.

000b27a0: 41646a75 7374206f 6374656f 6e5f6970    Adjust octeon_ip
000b2850: 73740a00 00000000 6f637465 6f6e5f72    st......octeon_r
000b2870: 5f73697a 65000000 6f637465 6f6e5f72    _size...octeon_r
000b2990: 6164696e 672e0a00 6f637465 6f6e5f72    ading...octeon_r
000b29b0: 785f7369 7a650000 6f637465 6f6e5f72    x_size..octeon_r
000b3050: 780a0000 00000000 6f637465 6f6e5f70    x.......octeon_p
000b3650: 6564204f 6374656f 6e206d6f 64656c0a    ed Octeon model.
000bade0: 20307825 71780a00 6f637465 6f6e5f6c     0x%qx..octeon_l
000bafd0: 696e6720 4f637465 6f6e2045 78656375    ing Octeon Execu
000bd710: 6564204f 6374656f 6e204d6f 64656c21    ed Octeon Model!
000bd950: 4f435445 4f4e2070 61737320 3120646f    OCTEON pass 1 do
000bda20: 6564206f 6374656f 6e206d6f 64656c3a    ed octeon model:

Хотяэти данные содержат некоторую полезную информацию, к сожалению, операционная система ( HiveOS ) не пытается распределить память непрерывно или объединить разрозненные кучи (и почему они должны?), поэтому подавляющее большинство памяти является бесплоднойКуча еще не будет malloc'd.

0004d6b0: 00000000 00000000 00000000 00000000    ................
0004d6c0: 00000000 00000000 00000000 00000000    ................
0004d6d0: 00000000 00000000 00000000 00000000    ................
0004d6e0: 00000000 00000000 00000000 00000000    ................
0004d6f0: 00000000 00000000 00000000 00000000    ................
0004d700: 00000000 00000000 00000000 00000000    ................
0004d710: 00000000 00000000 00000000 00000000    ................
0004d720: 00000000 00000000 00000000 00000000    ................
0004d730: 00000000 00000000 00000000 00000000    ................
0004d740: 00000000 00000000 00000000 00000000    ................
0004d750: 00000000 00000000 00000000 00000000    ................

Я бы хотел быстро и эффективно извлечь строки определенного размера, соответствующего произвольному шаблону регулярного выражения (на ум приходит [a-zA-z]). ВыМожно было бы подумать, что выполнение многолетних проверок дампа объекта любимых «строк» ​​даст результат, но утилита md является жестокой любовницей - из-за присутствия шестнадцатеричных банков и адресов в кодировке ascii она идентифицирует каждую строку как содержащую«строка».

Конечно, мы все знаем, что существует тривиальное решение для сценариев (for line in hexdump: f.write(line[-16:]) + grep '[A-z]' f).

Однако иногда я поражаюсь ощущению, что мне следует лучше понять эти подлые, угнетающие, но неправильно понятые регулярные выражения, а не возвращаться к своим простым в использовании новым языкам программирования.Я действительно чувствую, что не могу начать выращивать настоящую шейную бороду Unix, пока полностью не заменил всю свою среду разработки жизнь на различные потоковые редакторы и регулярные выражения скрипта Awk.

Как соответствовать одному[a-zA-z] в пределах определенного количества символов от конца строки (в моем случае, 16) - это выглядит как довольно емкая конструкция, но все сочетания +,?{16} и в других случаях, которые имели смысл для меня в последние несколько минут, быстро провалились.

Ответы [ 3 ]

6 голосов
/ 17 марта 2012

Используйте переключатель «несоответствие» -v:

grep -v \.{16}$

. Он удалит все строки, заканчивающиеся 16 точками.

Вот документация man для него:

-v, --invert-match
Инвертировать смысл соответствия, чтобы выбрать несовпадающие строки.

3 голосов
/ 15 марта 2012

Делает ли это то, что вы хотите?".{16}$"

Это будет соответствовать любым 16 символам в конце строки.$ гарантирует, что он соответствует концу строки.


После более тщательной проверки, если вы хотите извлечь только те строки, которые не являются всеми периодами, вы можете использовать это регулярное выражение: "{4}(.*?\w.*?)$" Перед {4} есть пробел, чтобы он соответствовал разделителю между цифрами и концом строки.Технически это не «всего 16 символов», но, учитывая набор данных, он действительно обеспечивает желаемый результат.(Предполагается, что желаемым выводом является любая строка, в которой есть символ слова, то есть буквы / цифры / подчеркивание.)

2 голосов
/ 17 марта 2012

Дешевый трюк для фильтрации интересных строк - заполнить выделение любым символом до конца строки.Здесь я выбираю символ, который не является точкой и не более 15 символов от конца строки.(Вы используете регулярное выражение posix, поэтому вы должны написать квантификатор повторения между \ {\} и не {})

grep '[^.].\{1,15\}$'

Затем вы можете передать результат с другим grep для тестирования или адаптировать идею к другомурегулярное выражение:

grep 'abc.\{1,13\}$'

будет содержать строку "abc" из 16 последних символов.

...