user
user

Reputation: 503

Capture date after regex using awk

I would like to print the regex "show memory compare.." and the date which comes after it from the testfile. The date may start with any day of the week.

ISSUE

ATTEMPT SO FAR

#!/bin/bash

day_of_week=$(locale day | tr ';' '\n' | cut -c 1-3 | tr '\n' '||')

awk -v day_of_week="$day_of_week" '
/show memory compare start/,/^day_of_week/
/show memory compare end/,/^day_of_week/

' testsnmpoutput.txt

TESTFILE (testsnmpoutput.txt)

xr_lab#   show clock
Thu Sep 19 14:38:02.812 WIB
14:38:02.893 WIB Thu Sep 19 2019
xr_lab#
xr_lab#show memory compare start
Thu Sep 19 14:38:06.400 WIB
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_start.out
xr_lab#
xr_lab#
xr_lab#
xr_lab#show memory compare end
Thu Sep 19 14:40:56.123 WIB
xr_lab#show memory compare start
Thu Sep 19 14:46:28.464 WIB
Successfully stored memory snapshot in /var/log/malloc_dump_memcmp_start.out
xr_lab#
xr_lab#
xr_lab#
xr_lab#
xr_lab#show memory compare end
show memory compare report
show process memory
Thu Sep 19 14:50:10.422 WIB

DESIRED OUTPUT

xr_lab#show memory compare start
Thu Sep 19 14:38:06.400 WIB
xr_lab#show memory compare end
Thu Sep 19 14:40:56.123 WIB
xr_lab#show memory compare start
Thu Sep 19 14:46:28.464 WIB
xr_lab#show memory compare end
Thu Sep 19 14:50:10.422 WIB

Thanks.

Upvotes: 1

Views: 200

Answers (4)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626794

You may use

day_of_week=$(locale day | sed 's/\([^;]\{3\}\)[^;]*/\1/g');
day_of_week="${day_of_week//;/|}";
p1='show memory compare (start|end)';
awk -v pat1="$p1" -v day_of_week="$day_of_week" '($0~pat1),($0~"^("day_of_week")"){ if ($0 ~ pat1 || $0 ~ "^("day_of_week")") print $0; }' file

See the online demo.

Details

  • $(locale day | sed 's/\([^;]\{3\}\)[^;]*/\1/g'); - gets the ;-separated day list and only keep 3 first letters of each day removing the rest
  • "${day_of_week//;/|}" - replaces all ; with |
  • p1='show memory compare (start|end)' defines the p1 variable containing the start range pattern (show memory compare start or show memory compare end)
  • The '($0~pat1),($0~"^("day_of_week")") gets the range of lines between start and end patterns (note you can't use /.../ notation with regexps passed as variables)
  • { if ($0 ~ pat1 || $0 ~ "^("day_of_week")") print $0; } only prints the lines matching starting or ending pattern.

More sed command details

The sed 's/\([^;]\{3\}\)[^;]*/\1/g' command uses a POSIX BRE pattern (as there is no -E, nor -P option) that matches:

  • \([^;]\{3\}\) - Capturing group 1:
    • [^;]\{3\} - three occurrences of any char but ;
  • [^;]* - 0 or more chars other than ;
  • \1 - the match is replaced with the contents of Group 1
  • g - all occurrences.

See the POSIX ERE pattern version demo (sed -E 's/([^;]{3})[^;]*/\1/g').

Upvotes: 0

Gautam
Gautam

Reputation: 1932

This oneliner should do :

$ grep -e 'show memory compare \(start\|end\)' -e '^\(Mon\|Tue\|Wed\|Thu\|Fri\)' testsnmpoutput.txt | grep -A 1 'show memory compare' | grep -v '^--'

Upvotes: 1

Lety
Lety

Reputation: 2603

try this:

/show memory compare start|show memory compare end/ {
   print;
   while (getline != 0) {
      if (match($1,"Mon|Tue|Wed|Thu|Fri|Sat|Sun") != 0) {
        print;
        break;
      }
   }
}

This code runs on lines that contain "show memory compare start" or "show memory compare end" and starting from there, loops through lines to find out the first line that starts with a day of week.

getline reads the next record of input and update $0 and NF.

Upvotes: 1

RavinderSingh13
RavinderSingh13

Reputation: 133478

Could you please try following.

awk '
BEGIN{
  num=split("mon,tue,wed,thu,fri,sat,sun",array,",")
  for(k=1;k<=num;k++){
      days[array[k]]
  }
}
/show memory compare start/{
  found_start=1
  start=$0
  next
}
found_start && tolower($1) in days{
  print start ORS $0
  found_start=start=""
}
/show memory compare end/{
  found_end=1
  end=$0
  next
}
found_end && tolower($1) in days{
  print end ORS $0
  found_end=end=""
}
'   Input_file

Upvotes: 1

Related Questions