Grep If The Next X Lines Doesn't Contain a Specific String

grep for a string in a line if the previous line doesn't contain a specific string

grep is really a line-oriented tool. It might be possible to achieve what you want with it, but it's easier to use Awk:

awk '
/xyz/ && !skip { print }
{ skip = /jkl/ }
' file

Read as: for every line, do

  • if the current line matches xyz and we haven't just seen jkl, print it;
  • set the variable skip to indicate whether we've just seen jkl.

awk searching for string if next X lines doesn't contain a specific string

Could you please try following and let me know if this helps you.

awk '{line=$0;gsub(/^ +/,"")} /^[0-9]+/{flag=""} /^[0-9]+/ && (/WARN/ || /Timeout failure/ || /Connection leak detection/){flag=1;if(val && val !~ /EAgent/){print val};val=""}  flag{val=val?val ORS line:line} END{if(val){print val}}' Input_file

Adding a non-one liner form of solution too now.

awk '
{
line=$0;
gsub(/^ +/,"")
}
/^[0-9]+/{
flag=""}
/^[0-9]+/ && (/WARN/ || /Timeout failure/ || /Connection leak detection/){
flag=1;
if(val && val !~ /EAgent/){
print val};
val=""
}
flag{
val=val?val ORS line:line}
END{
if(val){
print val}
}' Input_file


Explanation: Adding explanation of code too now for understanding and learning for all.

awk '
{
line=$0; ##Creating variable named line which will have current line value in it.
gsub(/^ +/,"") ##using gsub for removing initial space from each line to match.
}
/^[0-9]+/{ ##Checking condition if a line starts with digits then do following.
flag=""} ##Nullifying variable flag here.
/^[0-9]+/ && (/WARN/ || /Timeout failure/ || /Connection leak detection/){##Checking if a line starting from 0 to 9 and having either WARN, timeout or leak ones.
flag=1; ##Setting variable named flag value as 1 here.
if(val && val !~ /EAgent/){ ##Checking condition if variable val is NOT NULL and val NOT having string EAgent do follows.
print val}; ##Printing variable named val here.
val=""} ##Nullifying variable val here.
flag{ ##Checking condition if variable flag is NOT NULL here then do following.
val=val?val ORS line:line} ##Creating variable vale and concatenating its value with own value or have line variable in.
END{ ##Staring END section of awk code here now.
if(val){ ##Checking if variable val value is NOT NULL then do following.
print val} ##Printing the variable val value here.
}' Input_file ##Mentioning Input_file name here.

Grep regex NOT containing a string

grep matches, grep -v does the inverse. If you need to "match A but not B" you usually use pipes:

grep "${PATT}" file | grep -v "${NOTPATT}"

Negative matching using grep (match lines that do not contain foo)

grep -v is your friend:

grep --help | grep invert  

-v, --invert-match select non-matching lines

Also check out the related -L (the complement of -l).

-L, --files-without-match only print FILE names containing no match

Unix grep regex containing 'x' but not containing 'y'

^((?!beta).)*alpha((?!beta).)*$ would do the trick I think.

Match two strings in one line with grep

You can use

grep 'string1' filename | grep 'string2'

Or

grep 'string1.*string2\|string2.*string1' filename

How can I exclude one word with grep?

You can do it using -v (for --invert-match) option of grep as:

grep -v "unwanted_word" file | grep XXXXXXXX

grep -v "unwanted_word" file will filter the lines that have the unwanted_word and grep XXXXXXXX will list only lines with pattern XXXXXXXX.

EDIT:

From your comment it looks like you want to list all lines without the unwanted_word. In that case all you need is:

grep -v 'unwanted_word' file

Grep Regex: List all lines except

That should do it:

grep -v 'T[^H]'

-v : print lines not matching

[^H]: matches any character but H



Related Topics



Leave a reply



Submit