How to grep for a specific pattern and print everything above and below that pattern until you reach an indicator (LINUX)? - linux

So I am trying to grep for a specific pattern and then print everything above and below that pattern up to a specific indicator. I don't know if this is possible with grep or if I should you some other tool like awk, sed, or generate some shell script. So if I have the following:
---------------
.....
process: failed
......
----------------
and
----------------
.....
process: frozen
.....
----------------
I want to grep for 'process: frozen' and want everything between the dashed lines when 'process: frozen' is found. However the number of lines between the dashed lines may vary for different 'process: frozen' messages, so I can't count the number of lines above or below and use the -A and -B option of grep. Thank you in advance.

I would use GNU awk and set the record separator to a string which contains 16 hypens:
awk '/process: (failed|frozen)/' RS='-{16}' input.file

You can simply delete the line containing the process: frozen or process: failed message in sed.
sed "/process: frozen/d"

Related

Linux tail command includes more lines than intended

so I want to get a little into Linux scripting and started by a simple example in a book. In this book, the author wants me to grab the five lines before "Step #6: Configure output plugins" from snort.conf.
Analogous to the author I determined where the line is that I want, which returns 445 for me. If I then use tail the result returns more text than I expect and the searched line that should be in line 5 is at line 88. I fail to understand how I use the tail command and start at the specific line but then more text is included.
To search for the line I used
nl /etc/snort/snort.conf | grep output.
To get the 5 lines before including the searched line:
tail -n+440 /etc/snort/snort.conf | head -n+6
where as the tail statement seems to be the problem. Any help is appreciated on why my answer is not working!
Your tail command is correct in principle.
The problem lies in the way in which you acquire the line number using nl. The nl command does not count empty lines by default, while the tail command does. You should specify in your nl command that you want to count the empty lines as well, which you can do using the -b, (body-numbering) option and specify a as your style. This would look as follows:
nl -ba /etc/snort/snort.conf | grep output.
From nl --help:
Usage: nl [OPTION]... [FILE]...
Write each FILE to standard output, with line numbers added.
With no FILE, or when FILE is -, read standard input.
Mandatory arguments to long options are mandatory for short options too.
-b, --body-numbering=STYLE use STYLE for numbering body lines
[...]
By default, selects -v1 -i1 -l1 -sTAB -w6 -nrn -hn -bt -fn. CC are
two delimiter characters for separating logical pages, a missing
second character implies :. Type \\ for \. STYLE is one of:
a number all lines
t number only nonempty lines
Number all lines and use that line number in tail.
Hello in trying the same with same book that you are using but I didn’t find any great solution with tail or nl but i come up with simple grep switch -B and -A before and after switches for grep.
I achieved this issue by typing
grep -B 5 “Step #6: Configure output plugins “ /etc/snort/snort.conf
After that you will gonna get 5 lines before that line same for After -A for after lines.
Hope this will help someone staysafe happy learning 🙂

Find all lines with keyword and extract number

I would like to find line which starts from word: "ERRORS" and exctract number from that line.
Part of file:
...
[ERROR] No keywords and test cases defined in file
File path: libraries_instances.robot
TEST SUITES SUMMARY:
ERRORS: 148
WARNINGS: 89
CS VIOLATIONS: 201
My solution is:
grep ERRORS .validation.log | grep -o -E '[0-9]+'
is it possible to make it better and use only one grep?
Finally I would like to assign that value to variable in my bash script.
Since linux tag is present in question, assuming GNU grep with -P option is available
$ grep -oP 'ERRORS.*\h\K\d+' .validation.log
148
ERRORS.*\h\K here the \K option helps to mark the starting point of regex.. string matched up to this point won't be part of output
also note that man grep warns about using -P as experimental, but I haven't faced any issue so far.. (see https://debbugs.gnu.org/cgi/pkgreport.cgi?package=grep for known GNU grep issues)
Alternate solution using awk
$ awk '/ERRORS:/ && NF==2{print $NF}' .validation.log
148
/ERRORS:/ && NF==2 match line containing ERRORS: and has only two fields (by default, one or more contiguous whitespace is field delimiter)
print $NF print the last field

bash: write all lines starting with one of strings

I have a set of strings and want to write out all lines of a file that start with either of these.
Tried this that I found on the internet but that writes out the whole file... May I ask for a help? Thanks!
grep -Ev "^(58|11518|11909|11910|11911|11912|11913|11914|11915|11916|11917|11918|11919|11920|11921|11922|11923|11924|11925|11926|12055|12056|12060|12102|12103|12104|12105|12106|12107|12108|12109|12110|12111|12112|12113|12114|12115|12116|12117|12118|12119|12120|12121|12122|12123|12124|13813)" dead_end1_model.inp > newfile.txt
Your current invocation of grep only prints the inverse -v of the matches. I.e. any line not starting with any of those strings gets matched.
By your description you want to match the lines that do start with any of the strings, so just remove the -v from the invocation.

Print the line and a line 10 lines before the match in Linux

I want to match a string in a file, print the line which matches and the line 10 lines before the match occurs. I am trying using awk, sed and grep, but cant get the right thing. Can anyone help?
Try this command:
grep -B 10 PATTERN file.txt
The -A and -B options to GNU grep allow you to specify how much context should be displayed after and before the matching line.

Is there a way to put the following logic into a grep command?

For example suppose I have the following piece of data
ABC,3,4
,,ExtraInfo
,,MoreInfo
XYZ,6,7
,,XyzInfo
,,MoreXyz
ABC,1,2
,,ABCInfo
,,MoreABC
It's trivial to get grep to extract the ABC lines. However if I want to also grab the following lines to produce this output
ABC,3,4
,,ExtraInfo
,,MoreInfo
ABC,1,2
,,ABCInfo
,,MoreABC
Can this be done using grep and standard shell scripting?
Edit: Just to clarify there could be a variable number of lines in between. The logic would be to keep printing while the first column of the CSV is empty.
grep -A 2 {Your regex} will output the two lines following the found strings.
Update:
Since you specified that it could be any number of lines, this would not be possible as grep focuses on matching on a single line see the following questions:
How can I search for a multiline pattern in a file?
Regex (grep) for multi-line search needed
Why can't i match the pattern in this case?
Selecting text spanning multiple lines using grep and regular expressions
You can use this, although a bit hackity due to the grep at the end of the pipeline to mute out anything that does not start with 'A' or ',':
$ sed -n '/^ABC/,/^[^,]/p' yourfile.txt| grep -v '^[^A,]'
Edit: A less hackity way is to use awk:
$ awk '/^ABC/ { want = 1 } !/^ABC/ && !/^,/ { want = 0 } { if (want) print }' f.txt
You can understand what it does if you read out loud the pattern and the thing in the braces.
The manpage has explanations for the options, of which you want to look at -A under Context Line Control.

Resources