0

Newbie here. I am trying to use awk print a few information. So I wrote a shell scripts

#!/bin/bash

turbVar="U"
bcName="outlet"
str="$turbVar $bcName b.c. = "
# method-1
awk -v RS='}' '/'$bcName'/ { printf "%20s = %s\n" $str $4; exit;}' BCFile  | tr -d ";"
# method-2
awk -v RS='}' -v var1=$bcName '$0 ~ var1 { printf "%20s = %s\n" $str $4; exit;}' BCFile  | tr -d ";"

The BCFile file contents are

boundary
{
    inlet
    {
        type            fixedValue;
        value           uniform (5 0 0);
    }

    outlet
    {
        type            inletOutlet;
        inletValue      $internalField;
        value           $internalField;
    }

    ....
} 

I hope to output something like

U outlet b.c. = inletOutlet

Sadly, this does not work. it complains awk: (FILENAME=0/U FNR=4) fatal: not enough arguments to satisfy format string %20s = %s.

Why I can't use $str variable in awk printf?

Second question, which method is better? Using '/'$bcName'/ or using -v var1=$bcName '$0 ~ var1?, why I cant use '/$bcName/ or '/"$bcName"/directly? What is the difference between strong quote and weak quote here?

Daniel
  • 2,576
  • 7
  • 37
  • 51
  • What is `0/U` suppose to be? – Chris Seymour Apr 05 '13 at 17:48
  • It is a file. Its content is shown in this post `http://stackoverflow.com/questions/15825150/how-to-find-the-multiline-pattern-match-they-must-be-first-time-match` – Daniel Apr 05 '13 at 17:56
  • The file `U` is in a folder called `0`. :) – Daniel Apr 05 '13 at 17:58
  • @sudo_O - FYI you cannot name a file with a forward slash in it. Ditto for a nul character '\0'. – Ed Morton Apr 05 '13 at 18:56
  • @Daniel - wrt your question of `What is the difference between strong quote and weak quote`. What do you consider a "strong" vs 'weak" quote? We normally just talk about single and double quotes. In the case of your script just don't do any of the alternatives referred to in your question - they are both very bad. – Ed Morton Apr 05 '13 at 18:59

1 Answers1

3

You code cleaned up should be:

awk -v RS="}" -v v1="$bcName" -v s="$str" '$0~v1{gsub(/;/,"");printf "%s%s\n",s,$4;exit}' 
U outlet b.c. = inletOutlet

Notes:

  • Don't play with shell expansion and quoting it's a real headache. Pass in any shell variables nicely with -v.

  • You need to comma separator the arguments to printf.

  • Always quote your shell variables!

  • You should being doing gsub(/;/,"") inside the awk script instead of tr -d ";".

However it may not be the best approach but I couldn't say as no context was provied.

Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
  • No, it's not working. The output is messed up since there are many key word `outlet` in the file. :( – Daniel Apr 05 '13 at 18:06
  • 1
    That is because you want `$str` to be expanded from the shell -- which sudo_O probably missed... but the solution is in his answer: pass the value in with `-v str="$str"` – tzelleke Apr 05 '13 at 18:11
  • @TheodrosZelleke good spot missed that one, answer needs reworking anyway due to the new information given by OP. – Chris Seymour Apr 05 '13 at 18:17
  • LOL, @sudo_O, would you please also teach me how to add `gsub` in my case? So I dont need `tr` anymore. Thanks – Daniel Apr 05 '13 at 18:19
  • Btw, I am also surprised, since in shell no comma is needed for printf, but I have to use comman in awk. – Daniel Apr 05 '13 at 18:22
  • @Daniel - awk is not shell, just like C is not shell, Ada is not shell, etc. awk is it's own tool with it's own syntax which just bears some similarity to shell and C thanks to all 3 having been invented by the same company. – Ed Morton Apr 05 '13 at 18:55