Reputation: 647
grep -A 10 -f smallfile bigfile
greps every line from smallfile in bigfile and the next 10 lines too
is it possible by using another flag instead of -A to keep grepping the following lines until the occurence of a character (lets say @) in the bigfile, and I need to do it for hundreds of lines from smallfile and I have no information how many lines following the line from smallfile I need to grep, it changes for each. Example just illustrating one of the lines:
smallfile:
@123
@555
bigfile:
@123
abc
def
ghj
@789
sdf
tyu
rzx
@555
yui
wer
@435
teg
gdgd
So I want it to give me this
@123
abc
def
ghj
@555
yui
wer
If you know another way of "grepping" lines from one file in another file which can do this, that would also work, I may try to write a python script or a more complex loop, but I believe there should be a way to make grep do this using a flag like -m but I just couldn't make it work the way I want.
Many Thanks!
Upvotes: 3
Views: 562
Reputation: 6335
This job is better handled with awk than grep. Bellow script seems to work ok in my tests:
$ awk 'NR==FNR{a[$0];next}$0 in a{print;f=0;next} \
{if ($0 !~ /^@/ && f!=1) {print} else {f=1}}' smallfile bigfile
Or even:
awk 'NR==FNR{a[$0];next}$0 in a || ($0 !~ /^@/ && f!=1){print;f=0;next}{f=1}' file1 file2
Explanation:
awk scripts are based on pattern 'condition1{action1}condition2{action2}etc'
FNR
=Open File Line Number (resets on reading next file)
NR
=Global Line number - keeps increasing among all files
||
= OR logical operator
$0
=whole line
a[$0]
= initialize an array with $0 as key/index
$0 in a
= check if $0 (whole line) is a key/index of array a
$0 !~/^@/
=$0 do not match with regex /^@/ = not starting with @
next
=read next line
files are read serially by awk
Condition can be ommitted and action can be written directly. In this case action is always performed when will be reached by awk (equivalent to condition==1/true)
Action can be ommited for a given condition. In that case default action will be executed = print $0
Upvotes: 3