开发者

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


for grep -C is the straight forward option

for the 2nd question try this!

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


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


See head and/or tail.

For example:

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

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


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.


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.


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


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


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜