Why does awk '/^[^\t]/{a++}END{print a}' not count the empty lines (i.e. lines which only have new line character)? Isn't an empty line started not with \t tab?

  • can't reproduce, works fine – RomanPerekhrest Jan 7 '18 at 18:55
  • @RomanPerekhrest And you are sure you are testing correctly? – Hauke Laging Jan 7 '18 at 19:12
  • @HaukeLaging, ibb.co/iwHUjw – RomanPerekhrest Jan 7 '18 at 19:30
  • 8
    @RomanPerekhrest Then I guess you have misread the question as it states exactly what you have shown. – Hauke Laging Jan 7 '18 at 19:34
  • @HaukeLaging, I don't think that phrase not count the empty lines has many different meanings – RomanPerekhrest Jan 7 '18 at 19:39

Looking for something that isn't X isn't the same as looking for lines that don't contain X.

If we want to find lines that start with a tab, we can use the regex /^\t/. To find the opposite, i.e. lines that don't start with a tab, it's probably simplest to put the negation around the whole pattern (instead of in a character class):

awk '!/^\t/ {a++} END {print a+0}' 

a+0 so that a count of zero comes out as zero, instead of empty.

On the other hand, the regular expression [^\t] requires some character, it just can't be a tab.

If you want to match empty lines, then /^$/ or $0 == "". Or to match empty lines or lines with just whitespace /^[[:space:]]*$/ .

|improve this answer|||||

The reason is that [^\t] requires a character. The newline ($) does not count as character. You need this:

awk '/^([^\t]|$)/{a++}END{print a}'
|improve this answer|||||
  • 1
    $ is not a newline; it is the end of line, which can also be at the end of file where there is no newline character – mik Jan 22 '18 at 0:00

In regex, [^\t] doesn't mean "match where there isn't a \t". It means "match any character except \t". The critical difference is there has to be a character for it to match. In the case of an empty line, there isn't one.

|improve this answer|||||

I read the matching expression /^[^\t]/ as saying "lines that don't start with a tab". If you're looking for truly empty lines, this ought to work:

awk '/^$/{a +=1;};END{print a;}' /your/file/goes/here

The '^' means the beginning of the line, and '$' means the ending of the line, so putting them together means there's nothing between beginning and end. I haven't checked how this would behave on a CR-LF delimited line.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.