Arav
Arav

Reputation: 5247

Regarding grep command

I have two queries

  1. I do a grep and get the line number of the input file. i want to retrieve a set of lines before and after the line number from the inputfile and redirect to a /tmp/testout file. how can i do it.

  2. I have a line numbers 10000,20000. I want to retrieve the lines between 10000 and 20000 of the input file and redirect to a /tmp/testout file. how can i doi it

Upvotes: 1

Views: 415

Answers (8)

Dennis Williamson
Dennis Williamson

Reputation: 359965

If your grep doesn't have -A, -B and -C, then this sed command may work for you:

sed -n '1bb;:a;/PATTERN/{h;n;p;H;g;bb};N;//p;:b;99,$D;ba' inputfile > outputfile

where PATTERN is the regular expression your looking for and 99 is one greater than the number of context lines you want (equivalent to -C 98).

It works by keeping a window of lines in memory and when the regex matches, the captured lines are output.

If your sed doesn't like semicolons and prefers -e, this version may work for you:

sed -n -e '1bb' -e ':a' -e '/PATTERN/{h' -e 'n' -e 'p' -e 'H' -e 'g' -e 'bb}' -e 'N' -e '//p' -e ':b' -e '99,$D' -e 'ba' inputfile > outputfile

For your line range output, this will work and will finish a little more quickly if there are a large number of lines after the end of the range:

sed -n '100000,20000p;q' inputfile > outputfile

or

sed -n -e '100000,20000p' -e 'q' inputfile > outputfile

Upvotes: 0

Brian Rasmussen
Brian Rasmussen

Reputation: 116401

If you're using GNU grep, you can supply -B and -A to get lines before and after the match with grep.

E.g.

grep -B 5 -A 10 SearchString File

will give print each line matching SearchString from File plus 5 lines before and 10 lines after the matching line.

For the other part of your question, you can use head/tail or sed. Please see other answers for details.

Upvotes: 1

ghostdog74
ghostdog74

Reputation: 342323

you can do these with just awk, eg display 2 lines before and after "6", and display range from linenumber 4 to 8

$ cat file
1
2
3
4
5
6
7
8
9
10

$ awk 'c--&&c>=0{print "2 numbers below 6: "$0};/6/{c=2;for(i=d;i>d-2;i--)print "2 numbers above 6: "a[i];delete a}{a[++d]=$0} NR>3&&NR<9{print "With range: ->"$0}' file
With range: ->4
With range: ->5
2 numbers above 6: 5
2 numbers above 6: 4
With range: ->6
2 numbers below 6: 7
With range: ->7
2 numbers below 6: 8
With range: ->8

Upvotes: 0

Abubacker Nainamohamed
Abubacker Nainamohamed

Reputation: 4797

for grep -C is the straight forward option

for the 2nd question try this!

sed -n "100000,20000p" bar.txt > foo.txt 

Upvotes: 8

nonopolarity
nonopolarity

Reputation: 150976

to see the before and after: (3 lines before and 3 lines after)

grep -C3 foo bar.txt

the second question:

head -20000 bar.txt | tail -10000 > foo.txt

Upvotes: 0

paxdiablo
paxdiablo

Reputation: 881273

For part 2, awk will allow you to print a range of lines thus:

awk 'NR==10000,NR==20000{print}{}' inputfile.txt >/tmp/testout

This basically gives a range based on the record number NR.

For part 1, context from grep can be obtained using the --after-context=X and --before-context=X switches. If you're running a grep that doesn't allow that, you can dummy up an awk script based on the part 2 answer above.

Upvotes: 0

jhenninger
jhenninger

Reputation: 707

You want to look into the -A -B and -C options of grep. See man grep for more information

   -A NUM, --after-context=NUM
          Print  NUM  lines  of  trailing  context  after  matching lines.
          Places  a  line  containing  --  between  contiguous  groups  of
          matches.

   -B NUM, --before-context=NUM
          Print NUM  lines  of  leading  context  before  matching  lines.
          Places  a  line  containing  --  between  contiguous  groups  of
          matches.

   -C NUM, --context=NUM
          Print  NUM lines of output context.  Places a line containing --
          between contiguous groups of matches.

For redirecting the output, do the following: grep "your pattern" yourinputfile > /tmp/testout

Upvotes: 2

ypnos
ypnos

Reputation: 52327

See head and/or tail.

For example:

head -n 20000 <input> | tail -n 10000 > /tmp/testout

whereas the argument of tail is (20000 - 10000).

Upvotes: 1

Related Questions