Sometime we may need to check if a text file contains the wanted information which can be in one line or two sequential lines, but not others. For example we may check if a file contains the "operation system" and "Linux". It limits to the following format:
In one line:
"operation system Linux" or "operation systems such as Unix, Linux, Windows..."
or
"operation system
Linux"
or
"operation systems such
as Unix, Linux, Windows... "
but not
"Linux operation system"
not
"Linux
operation system"
not
"operation system
......
Linux"
pcregrep
pcregrep -M 'operation system.*(\n|.).*Linux' test.txt
awk
awk '/operation system/{k=1; ln=$0} /Linux/{if(k == 1){print "--------"; print ;} if(k == 2){print "---------"; print ln; print;}} {if(k > 0){k++}}' test.txt
Problem: this awk will match the "Linux operation system"? How to avoid it?
Improvement:
./match.awk test.txt
match.awk
#!/usr/bin/awk -f
BEGIN \
{
print " - BEGIN - "
m1 = 0; # mark1
m2 = 0; # mark2
ln = ""; # last line
}
{
# two marks in one line
if ($0 ~ /operation system.*Linux/) {
print "----1----";
print $0;
}
else {
if ($0 ~ /operation system/) {
m1 = 1;
ln = $0;
}
else if ($0 ~ /Linux/ && m1 == 1) {
# two marks in adjacent lines
m2 = 1;
print "----2----";
print ln;
print $0;
}
else {
# clear all variables for unmatched line
m1 = 0;
m2 = 0;
ln = "";
}
}
}
END { print " - DONE - " }
Test Output
- BEGIN -
----1----
operation system Linux
----2----
operation system
Linux
----1----
operation system such as Linux
----2----
operation system
such as Linux
- DONE -
Test Input: test.txt
operation system Linux
operation system
Linux
operation system such as Linux
operation system
such as Linux
Linux
operation system
Linux operation system
operation system
Linux
operation system
such as
Linux