Reputation: 503
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
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
)'($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
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
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
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