0

I'm trying to print records from line number from 10 to 15 from input file number-src. I tried with below code but it prints all records irrespective of line number.

awk '{
count++
if ( $count >= 10 ) AND ( $count <= 15 )
 {
  printf "\n"  $0
 }
}' number_src
Ben Grimm
  • 4,316
  • 2
  • 15
  • 24
Madan
  • 75
  • 8
  • Errr I just closed it as duplicate of [How can I extract a range of lines from a text file on Unix?](http://stackoverflow.com/q/83329/1983854) and now it is open again. I don't understand what happened and http://stackoverflow.com/posts/28608864/timeline doesn't give much information. – fedorqui Feb 19 '15 at 14:33
  • @fedorqui, Although it's the same subject as extracting a range, the real question here isn't *How can I extract a range of lines?* as much as it's a question of, *Why doesn't this method of extracting a range of lines work?* which is a different question. – lurker Feb 19 '15 at 14:37
  • I agree with you regarding this being a "why" instead of "how", although I guess the answers will be mainly in the "how" form. The thing is that the approach is quite overkilling, since it can be done in just a line, mainly the way it is described in the suggested duplicate. Also, my comment was regarding "how" this reopening happened :P I guess Ed Morton reopened the question but I cannot see it from the logs. – fedorqui Feb 19 '15 at 14:41
  • @fedorque I agree: how the question reopened is a puzzle. :) I don't think the question is really yet answered, even with Ed's response. If you replace the OP's `printf` with `printf count ":" $0 "\n"` it prints every line with `count` increasing from 1 to the number of lines in `number_src`. That begs the question: *Why doesn't the `if` statement seem to take effect here?* – lurker Feb 19 '15 at 14:47
  • @lurker The answer to that question is exactly what Ed answered. The syntax is wrong. In `awk` variables are not referenced by a preceding `$` sign. There is no `AND` operator and the way `if` conditional is wrapped around conditional is incorrect. Also, what by what it seems OP is trying to achieve can be done using `NR` built-in variable. – jaypal singh Feb 19 '15 at 14:53
  • @jaypalsingh No, not to detract form Ed's reply, he offered a valid and more canonical *alternative* approach (using `NR`) but did *not* answer the question of what's wrong with the OP's syntax. That answer was given by Behe. – lurker Feb 19 '15 at 14:54
  • @lurker uhms you mentioned me as "fedorque" and I didn't get the notification. I finally found out the reopening: it was done by Ed http://stackoverflow.com/posts/28608864/revisions – fedorqui Feb 19 '15 at 15:36
  • @fedorqui oops, sorry about the typo.... Thanks for figuring that out. – lurker Feb 19 '15 at 15:37
  • @EdMorton So you reopen the question to suggest a book and write the same command that appears in the duplicate question ;) I accept the question to be reopened if it is to explain "why" the OP approach is bad. For the "how", you may instead keep it closed and use comments. – fedorqui Feb 19 '15 at 16:44
  • @EdMorton those are good comments. Why not enumerate the key problems with the OP's script in your answer to directly answer their question (in addition to showing them a more correct way, as you did)? I think that would help them. – lurker Feb 19 '15 at 16:44
  • 1
    @EdMorton sorry you deleted your comment and answer. I think your comment and answer were of value. I do understand the perspective. I guess it gets into the question of: if a beginner gets some number of fundamental things wrong, what's the best approach to help right it? I don't consider my opinion more valuable than yours. Probably no one fixed right answer to that question, and probably belongs in some meta-discussion somewhere... – lurker Feb 19 '15 at 17:03
  • @lurker IMHO there's really just 2 ways to help the OP when they post a script in which everything is wrong: 1) enumerate every problem and explain why they are problems with examples of the correct way(s) to do it, or 2) Refer them to the book that teaches the language. I'm not willing to do the former as I won't spend that much time on a question and I feel it could mislead the OP into thinking that is all they need so I did the latter but I understand others feeling that the former would be more useful and so I've removed my answer and comments to leave the door open for someone to do that. – Ed Morton Feb 19 '15 at 17:08
  • 2
    @EdMorton thanks, I can understand and appreciate that position. My opinion is that you should undelete your answer, as it illustrated the most correct `awk` way to solve it, and you recommended a good book (which was helpful to me as well). I found that book online in [PDF format](http://www.gnu.org/software/gawk/manual/gawk.pdf). – lurker Feb 19 '15 at 17:14
  • 3
    @lurker - yes the book is freely available online but I recommend everyone buy a copy as it's useful to have around and more importantly the guy who wrote it and is the provider for gawk deserves to make a few bucks off all of his hard work and that's the only way he gets any money from it. I'll undelete my answer. – Ed Morton Feb 19 '15 at 17:27
  • 1
    Thanks @EdMorton I agree. I would prefer a printed copy of the book anyway as I personally find it more convenient to reference while working. – lurker Feb 19 '15 at 17:37

2 Answers2

4

awk is not bash just like C is not bash, they are separate tools/languages with their very own syntax and semantics:

awk 'NR>=10 && NR<=15' number_src

Get the book Effective Awk Programming, by Arnold Robbins.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
4

Two issues why your script is not working:

  • logical AND should be &&.
  • use count as variable name, when referencing it, not $count.

Here is a working version:

awk '{
     count++
     if ( count >= 10  &&  count <= 15 )
     {
          print $0
     }
     }' numbers_src

As stated in the quickest answer, for your task NR is the awk-way to do the same task.

For further information, please see the relevant documentation entries about boolean expressions and using variables.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
Behe
  • 7,572
  • 3
  • 33
  • 46