I have a file with about 1000 lines. I want the part of my file after the line which matches my grep statement.
That is:
$ cat file | grep 'TERMINATE' # It is found on line 534
So, I want the file from line 535 to line 1000 for further processing.
How can I do that?
If for any reason, you want to avoid using sed, the following will print the line matching TERMINATE
till the end of the file:
tail -n "+$(grep -n 'TERMINATE' file | head -n 1 | cut -d ":" -f 1)" file
and the following will print from the following line matching TERMINATE
till the end of the file:
tail -n "+$(($(grep -n 'TERMINATE' file | head -n 1 | cut -d ":" -f 1)+1))" file
It takes 2 processes to do what sed can do in one process, and if the file changes between the execution of grep and tail, the result can be incoherent, so I recommend using sed. Moreover, if the file dones not contain TERMINATE
, the 1st command fails.
These will print all lines from the last found line "TERMINATE" till end of file:
LINE_NUMBER=`grep -o -n TERMINATE $OSCAM_LOG|tail -n 1|sed "s/:/ \\'/g"|awk -F" " '{print $1}'`
tail -n +$LINE_NUMBER $YOUR_FILE_NAME
grep -A 10000000 'TERMINATE' file
As a simple approximation you could use
grep -A100000 TERMINATE file
which greps for TERMINATE
and outputs up to 100000 lines following that line.
From man page
-A NUM, --after-context=NUM
Print NUM lines of trailing context after matching lines. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.
If I understand your question correctly you do want the lines after TERMINATE
, not including the TERMINATE
-line. awk
can do this in a simple way:
awk '{if(found) print} /TERMINATE/{found=1}' your_file
Explanation:
if(found) print
) will not print anything to start off with.This will print all lines after the TERMINATE
-line.
Generalization:
Example:
$ cat ex_file.txt
not this line
second line
START
A good line to include
And this line
Yep
END
Nope more
...
never ever
$ awk '/END/{found=0} {if(found) print} /START/{found=1}' ex_file.txt
A good line to include
And this line
Yep
$
Explanation:
found
is set.found=1
so that the following lines are printed. Note that this check is done after the actual printing to exclude the start-line from the result.Notes:
BEGIN{found=0}
to the start of the awk-expression.This could be a one way of doing it. If you know what line of the file you have your grep word and how many lines you have in your file:
grep -A466 'TERMINATE' file
sed is a much better tool for the job: sed -n '/re/,$p' file
where re is regexp.
Another option is grep's --after-context flag. You need to pass in a number to end at, using wc on the file should give the right value to stop at. Combine this with -n and your match expression.
Alternatives to the excellent sed
answer by jfgagne, and which don't include the matching line :
awk '/TERMINATE/ {y=1;next} y'
( https://stackoverflow.com/a/18166628 )awk '/TERMINATE/ ? c++ : c'
( https://stackoverflow.com/a/23984891 )perl -ne 'print unless 1 .. /TERMINATE/'
( https://stackoverflow.com/a/18167194 )A tool to use here is awk:
cat file | awk 'BEGIN{ found=0} /TERMINATE/{found=1} {if (found) print }'
How does this work:
The other solutions might consume a lot of memory if you use them on very large files.
Use bash parameter expansion like the following:
content=$(cat file)
echo "${content#*TERMINATE}"
There are many ways to do it with sed
or awk
:
sed -n '/TERMINATE/,$p' file
This looks for TERMINATE
in your file and prints from that line up to the end of the file.
awk '/TERMINATE/,0' file
This is exactly the same behaviour as sed
.
In case you know the number of the line from which you want to start printing, you can specify it together with NR
(number of record, which eventually indicates the number of the line):
awk 'NR>=535' file
$ seq 10 > a #generate a file with one number per line, from 1 to 10
$ sed -n '/7/,$p' a
7
8
9
10
$ awk '/7/,0' a
7
8
9
10
$ awk 'NR>=7' a
7
8
9
10
Source: Stackoverflow.com