Вычитание значения из строки с помощью регулярного выражения - PullRequest
0 голосов
/ 28 февраля 2012

Есть какой-то лог-файл.

$> cat ./text
Tue, 28 Feb 2012 15:43:20 407a3f8bbf704e41bef1f4c0ac24f310 FAILED
Tue, 2012 15:45:10 525b13aed6094417a56fd7bc67a10ad7 FAILED
Tue, 28 Feb 2012 15:47:08 ae3e2dc3e5b14d0eb7338ab308a32c8e
Tue, Feb 2012 15:52:26 18486cbede4e4cb4bee931bf29823dda FAILED
Tue, 28 Feb 2012 15:54:17 3c96983a68dd4c5e968dcad512bf77e9 FAILED
Tue, Feb 2012 15:56:30 2191e5260aa44a2a8997c47d710d6fbb FAILED
Tue, 28 Feb 2012 15:58:25 083fc56361414695b4e5cf54f8c57a9e FAILED
28 Feb 2012 16:01:55 5cbad64d2d62429c97ed7fdf98087c44 FAILED
Tue, 28 Feb 2012 16:03:37 a0d33b998b8247ffbecb984198453c0b
28 Feb 2012 16:05:32 cf9c1893e8b64aa89636a8cfeff56cf2 FAILED
Tue, 28 Feb 2012 16:06:53 027d99f7fa68436d9000661a7af07e2a PASSED

Все эти шестнадцатеричные значения легко получить с помощью grep.

$> grep --only-matching --perl-regex "[0-9a-f]{32}" ./text
407a3f8bbf704e41bef1f4c0ac24f310
525b13aed6094417a56fd7bc67a10ad7
ae3e2dc3e5b14d0eb7338ab308a32c8e
18486cbede4e4cb4bee931bf29823dda
3c96983a68dd4c5e968dcad512bf77e9
2191e5260aa44a2a8997c47d710d6fbb
083fc56361414695b4e5cf54f8c57a9e
5cbad64d2d62429c97ed7fdf98087c44
a0d33b998b8247ffbecb984198453c0b
cf9c1893e8b64aa89636a8cfeff56cf2
027d99f7fa68436d9000661a7af07e2a

Но как мне это сделать с awk?

Итак, актуальный вопрос: как я могу вычесть какое-то значение, соответствующее некоторому регулярному выражению, для заданной строки? Например, в некоторой строке awk -источника у меня есть значение $ 0, которое на самом деле представляет собой целую строку, например "Tue, Feb 2012 15:56:30 2191e5260aa44a2a8997c47d710d6fbb FAILED". Я ищу команду awk для получения шестнадцатеричного значения, например:

 hex = command_name( $0, "[0-9a-f]{32}" )

А hex будет равен 2191e5260aa44a2a8997c47d710d6fbb.

Как я могу это сделать?

Ответы [ 6 ]

1 голос
/ 28 февраля 2012

Вы можете использовать match () для этого (gawk может потребоваться для --re-interval):

$ gawk --re-interval '{ match($0, /[0-9a-fA-F]{32}/,arr); print arr[0]; }' testdata 
407a3f8bbf704e41bef1f4c0ac24f310
525b13aed6094417a56fd7bc67a10ad7
ae3e2dc3e5b14d0eb7338ab308a32c8e
18486cbede4e4cb4bee931bf29823dda
3c96983a68dd4c5e968dcad512bf77e9
2191e5260aa44a2a8997c47d710d6fbb
083fc56361414695b4e5cf54f8c57a9e
5cbad64d2d62429c97ed7fdf98087c44
a0d33b998b8247ffbecb984198453c0b
cf9c1893e8b64aa89636a8cfeff56cf2
027d99f7fa68436d9000661a7af07e2a
0 голосов
/ 29 февраля 2012

Если ваш файл журнала последовательно структурирован, как показано в примере:

awk '{print $6}' ./text
0 голосов
/ 29 февраля 2012

Это может сработать или вам:

awk --re-interval -vRS='[0-9a-fA-F]{32}' 'RT{print RT}' file
0 голосов
/ 29 февраля 2012

не-GNU awk ответ

awk '
  {
    for (i=NF; i>0; i--)
      if (length($i)==32 && ! match($i,/[^0-9a-fA-F]/)) {
        hexvalue = $i
        break  # if you only expect one per line
      }
    print hexvalue    # or do something else
  }
'
0 голосов
/ 28 февраля 2012

Может быть, вы можете попробовать расширение GNU gensub()

$ awk --re-interval '{print gensub(/^.*([0-9a-f]{32}).*$/,"\\1","")}' text
407a3f8bbf704e41bef1f4c0ac24f310
525b13aed6094417a56fd7bc67a10ad7
ae3e2dc3e5b14d0eb7338ab308a32c8e
18486cbede4e4cb4bee931bf29823dda
3c96983a68dd4c5e968dcad512bf77e9
2191e5260aa44a2a8997c47d710d6fbb
083fc56361414695b4e5cf54f8c57a9e
5cbad64d2d62429c97ed7fdf98087c44
a0d33b998b8247ffbecb984198453c0b
cf9c1893e8b64aa89636a8cfeff56cf2
027d99f7fa68436d9000661a7af07e2a
0 голосов
/ 28 февраля 2012

Оригинальная программа awk не поддерживает обратные ссылки в regex-replace.Если вам повезло и у вас есть доступ к GNU awk, вы можете использовать функцию sub() для извлечения частей строки.Теоретически это работает так:

hex = sub(/^.* ([0-9a-fA-F]+) .*$/, "\1");

Поскольку у меня нет GNU awk в моих руках на данный момент, вам придется поиграться, чтобы найти правильный синтаксис (например, "\1" против "\\1", + против {32,32} и т. Д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...