# AWK Script and Commandline difference

**URL:** <https://community.unix.com/t/awk-script-and-commandline-difference/290671>\
**Category:** Shell Programming and Scripting\
**Created:** [June 29, 2011, 10:08am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671 "2011-06-29T10:08:24Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![MrSnail](https://community.unix.com/letter_avatar/mrsnail/32/5_5575768a8748004e209b776fc1b2916d.png) [@MrSnail](https://community.unix.com/u/MrSnail)\
**Post date:** [June 29, 2011, 10:08am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/1 "2011-06-29T10:08:24Z")

</div>

Hey there,

I just stumbled upon a difference between using awk on the commandline and using it in a shellscript.

I have a variable, e.g.: PROG=vim  
then i want to check if the package with this name is installed: TEMPVAL=$(dpkg -l | awk '{ if ($2 == "$PROG") print $2 }') (Im using Tempval later in an condition to check if it is installed)  
Running this on the commandline works fine. In the shellscript TEMPVAL is always empty.

btw "toinstall" just contains some package names to be installed and comments prefixed with #

full script:

```nohighlight
#!/bin/bash

for prog in `cat toinstall | grep -vP "^#" | grep -vP "^$"`
do
    TEMPVAL=$(`dpkg -l | awk '{ if ($2 == "${prog}") print $2}'`)
    if ["$TEMPVAL" == ""]
    then
    sudo apt-get install -y $prog
    fi
done

```

bash -x output:

```nohighlight
+ for prog in '`cat toinstall | grep -vP "^#" | grep -vP "^$"`'
+++ dpkg -l
+++ awk '{ if ($2 == "${prog}") print $2}'
+ TEMPVAL=
+ '[' '' == '' ']'
+ sudo apt-get install -y vim

```

Whats the Problem?:wall: I already tried playing with the quotation, but nothing worked. Hope somebody can help me. I'd also appreciate hints or tips if theres a more convenient way of doing what i want to do :b:

Greetings, MrSnail

---

<div class="post-metadata">

**Author:** ![aigles](https://community.unix.com/user_avatar/community.unix.com/aigles/32/118_2.png) [@aigles](https://community.unix.com/u/aigles)\
**Post date:** [June 29, 2011, 10:12am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/2 "2011-06-29T10:12:52Z")

</div>

```nohighlight
TEMPVAL=$(dpkg -l | awk '{ if ($2 == "'${prog}'") print $2}')

```

Or (my prefred way):

```nohighlight
TEMPVAL=$(dpkg -l | awk '{ if ($2 == prog) print $2}' prog="${prog}")

```

Jean-Pierre.

---

<div class="post-metadata">

**Author:** ![yazu](https://community.unix.com/user_avatar/community.unix.com/yazu/32/7048_2.png) [@yazu](https://community.unix.com/u/yazu)\
**Post date:** [June 29, 2011, 10:16am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/3 "2011-06-29T10:16:22Z")

</div>

```plaintext
awk '{ if ($2 == "'"$prog"'") print $2}'

```

[This article](http://www.shelldorado.com/goodcoding/awkinvoke.html) describes three ways to interface AWK programs with shell scripts and how to import shell variables into AWK programs.

But a little better:

```plaintext
awk '$2 == "'"$prog"'" {print $2}'

```

The inner double quotes are really not needed here but this is a good habit.

---

<div class="post-metadata">

**Author:** ![MrSnail](https://community.unix.com/letter_avatar/mrsnail/32/5_5575768a8748004e209b776fc1b2916d.png) [@MrSnail](https://community.unix.com/u/MrSnail)\
**Post date:** [June 29, 2011, 10:17am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/4 "2011-06-29T10:17:32Z")

</div>

Well,... that was quite easy 😃  
Thanks a lot for this fast response. 🙂

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/5_5575768a8748004e209b776fc1b2916d.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [June 29, 2011, 11:08am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/5 "2011-06-29T11:08:03Z")

</div>

> [@yazu](#):
>
> ```plaintext
> awk '{ if ($2 == "'"$prog"'") print $2}'
> 
> ```
> 
> [This article](http://www.shelldorado.com/goodcoding/awkinvoke.html) describes three ways to interface AWK programs with shell scripts and how to import shell variables into AWK programs.
> 
> But a little better:
> 
> ```plaintext
> awk '$2 == "'"$prog"'" {print $2}'
> 
> ```
> 
> The inner double quotes are really not needed here but this is a good habit.

It's actually a pretty bad habit -- there's a much better way to get variables into awk, -v. No need to mess with ending and beginning single and double quotes inside the awk script itself.

```plaintext
awk -v VAR="$prog" '$2 == VAR { print $2 }'

```

---

<div class="post-metadata">

**Author:** ![yazu](https://community.unix.com/user_avatar/community.unix.com/yazu/32/7048_2.png) [@yazu](https://community.unix.com/u/yazu)\
**Post date:** [June 29, 2011, 11:17am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/6 "2011-06-29T11:17:26Z")

</div>

I wrote about quoting shell variables not about embedding.

Maybe you true about awk but the "pretty bad" way is universal - it's for perl, sed, python or almost anything other, where you want to embed shell variables.

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/5_5575768a8748004e209b776fc1b2916d.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [June 29, 2011, 11:37am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/7 "2011-06-29T11:37:21Z")

</div>

> [@yazu](#):
>
> I wrote about quoting shell variables not about embedding.
> 
> Maybe you true about awk but the "pretty bad" way is universal

It's a bad idea because it becomes language syntax, not merely a string. This is especially bad for a variable, where you might not have strict control over the exact contents:

```plaintext
$ STR="hello 'world'"
$ awk 'BEGIN { print "'$STR'" }'
awk: BEGIN { print "hello
awk: ^ unterminated string
$

```

> [@](#):
>
> it's for perl

```plaintext
 VAR="this will barf'"
# subsitute in the shell and it barfs, taking the extra ' as perl syntax
$ perl -e "print '$VAR', "\n";'
Can't find string terminator '"' anywhere before EOF at -e line 1.
# do it properly and it will not.
$ perl -e 'print shift, "\n"' "$VAR"
this will barf'
$

```

> [@](#):
>
> ...sed, python or almost anything other, where you want to embed shell variables.

I admit there's no good way to do it in sed, but this is an argument against sed, not an argument for that syntax. It's very difficult to safely put variables in sed because so many things need escaping.

And if the argument is that you don't need to memorize syntax for each language, well, you already had to memorize -e for perl, how much harder is -v, shift, etc?

---

<div class="post-metadata">

**Author:** ![yazu](https://community.unix.com/user_avatar/community.unix.com/yazu/32/7048_2.png) [@yazu](https://community.unix.com/u/yazu)\
**Post date:** [June 29, 2011, 11:52am UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/8 "2011-06-29T11:52:34Z")

</div>

> [@](#):
>
> ```plaintext
> $ STR="hello 'world'"
> $ awk 'BEGIN { print "'$STR'" }'
> 
> ```

But i wrote exactly about this! Put shell variables inside double quotes:

```plaintext
$ STR="hello 'world'"
app@kf3sv ~
$ awk 'BEGIN { print "'"$STR"'" }'
hello 'world'

```

```plaintext
$ perl -e 'print "'"$VAR"'", "\n";'
this will barf'

```

And yes - threre is not an universal "safe" way to embed shell variables. But I believe there is not any universal way to write "safe" shell scripts. Shell is a command language, you know - for those who write and execute commands.

And I repeat one more:  
The inner double quotes are really not needed here but this is a good habit.

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/5_5575768a8748004e209b776fc1b2916d.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [June 29, 2011, 12:08pm UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/9 "2011-06-29T12:08:44Z")

</div>

> [@yazu](#):
>
> But i wrote exactly about this! Put shell variables inside double quotes:
> 
> ```plaintext
> $ STR="hello 'world'"
> app@kf3sv ~
> $ awk 'BEGIN { print "'"$STR"'" }'
> hello 'world'
> 
> ```

Okay, how about:

```plaintext
$ STR="hello \"world\""
$ awk 'BEGIN { print "'"$STR"'" }'
hello
$ STR='"; system("/sbin/poweroff") ; print "'
$ awk 'BEGIN { print "'"$STR"'" }'

poweroff: must be superuser.

$ awk -v VAR="$STR" 'BEGIN { print VAR }'
"; system("/sbin/poweroff") ; print "
$

```

Extra quotes don't protect you no matter how many of them you have. They do leave you wide open to bizzare errors and intentional abuse. The -v syntax eliminates all these problems.

> [@](#):
>
> And yes - threre is not an universal "safe" way to embed shell variables.

Your method isn't merely imperfect, it's downright unsafe.

---

<div class="post-metadata">

**Author:** ![yazu](https://community.unix.com/user_avatar/community.unix.com/yazu/32/7048_2.png) [@yazu](https://community.unix.com/u/yazu)\
**Post date:** [June 29, 2011, 12:23pm UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/10 "2011-06-29T12:23:14Z")

</div>

Well, enough. Just only - it is not my method - it's common practice to embed shell variables in perl, sed, sql etc.

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/5_5575768a8748004e209b776fc1b2916d.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [June 29, 2011, 12:34pm UTC](https://community.unix.com/t/awk-script-and-commandline-difference/290671/11 "2011-06-29T12:34:25Z")

</div>

If it really is "common practice" that's alarming.

I don't understand your defensiveness. There may be situations where substituting strings into the program text itself is the only option(I already demonstrated how to avoid that in perl with shift), but this topic, about awk, isn't one of them.
