0

I'm translating a csh script to bash an came across a line that looks like

@ lines = `grep num_lines ../config.txt | awk '{printf("%d",int($2))}' `

What does the '@' do here? I found some documentation stating that csh uses '@' for expressions. However, this looks like a normal variable assignment to me. When I run the grep and awk part of the code in bash the output is an integer with a preceding '%d', e.g. '%d 12045'.

4
  • Are you sure that the awk command says print and not printf? May 11, 2019 at 4:26
  • That line's broken and never worked properly. It will die out with an Ambiguous error. (or Expression Syntax in tcsh).
    – user313992
    May 11, 2019 at 5:53
  • @Scott You are right, it's printf indeed.
    – Loibologic
    May 12, 2019 at 17:10
  • No need for grep. Use lines=$(awk '/num_lines/ {print $2}' ../config.txt) or even lines=$(awk '$1=="num_lines" {print $2}' ../config.txt) May 12, 2019 at 19:17

1 Answer 1

1

Well, it’s impossible to know what the author of that script was thinking.  But here are some observations:

  • If the awk command, indeed, says printf, then it is printing the integer value of the second string on the input line.
  • As roaima commented, and as I have been known to comment, awk is a very powerful program.  You almost never need to run it in combination with grep, sed, or another awk.  So
    grep num_lines filename | awk '{ printf("%d", int($2)) }'
    can be written
    awk '/num_lines/ { printf("%d", int($2)) }' filename
  • As I mentioned above, int($2) gives you the integer part of the second string on the input line.  So, if the config file says num_lines   foo, you will get 0.  If it says num_lines   3.14, you will get 3.  It seems unlikely that you would need to take such precautions with a well-formed configuration file.
  • In any case,
    printf("%d", int($2))
    is overkill.  As far as I can tell,
    printf("%d", $2)
    and
    print int($2)
    are (almost) exactly equivalent.
  • The one difference that I can identify is that the printf version doesn’t write a newline at the end:
    $ echo "num_lines   42" | awk '{printf("%d", $2)}'; date
    42Mon, May 13, 2019 12:00:00 AM
     
    $ echo "num_lines   42" | awk '{print int($2)}'; date
    42
    Mon, May 13, 2019 12:00:01 AM
    but this isn’t really relevant, since `…` strips off a trailing newline.
  • You say “this looks like a normal variable assignment to me”.  But users of [t]csh know that it doesn’t allow
    variable=value
    you have to say
    set variable=value
    or
    @ variable=expr
    Of course a simple integer constant is a valid expr, so the author may simply be using @ instead of set because it’s shorter and they know that the value is an integer.

So the statement is setting the lines variable to the value of num_lines from ../config.txt.

1
  • Thanks for the comprehensive answer! I did not know this convenient way to look for specific strings with awk. lines=$( awk '/num_lines/ {print int($2)}' ../config.txt ) works perfect (in bash).
    – Loibologic
    May 13, 2019 at 12:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .