1
votes

I am unable to read fields from awk command in Tcl while it runs in a terminal but not in Tcl script.

Tried making syntax changes, it works in terminal not in script

set a { A B C D E F G H I J K L M N O P Q R S T U V W X Y Z }

#store only cell var in file
exec grep -in "cell (?*" ./slow.lib | cut -d "(" -f2 | cut -d ")" -f1 > cells.txt

#take alphabets to loop
foreach  b $a {
puts "$b\n"

if { [ exec cat cells.txt | awk ' $1 ~ /^$b/ ' ] } {

    foreach cell [exec cat ./cells.txt] {
    puts "$b \t $cell"
    }

}

The condition should check for first char in the file and give boolean. The error is:

can't read "1": no such variable while executing "exec cat cells.txt | awk ' $1 ~ /^$b/ ' "

2

2 Answers

1
votes

Your problem is that Tcl attaches no special meaning at all to the ' character. It uses {…} (which nest better) for the same purpose. Your command:

exec cat cells.txt | awk ' $1 ~ /^$b/ '

should become:

exec cat cells.txt | awk { $1 ~ /^$b/ }

Except… you also want $b (but not $1) to be substituted in there. The easiest way to do that is with format:

exec cat cells.txt | awk [format { $1 ~ /^%s/ } $b]

It would be more optimal to omit the use of cat here:

exec awk [format { $1 ~ /^%s/ } $b] <cells.txt

You are aware that your whole script can be written in pure Tcl without any use of exec?

0
votes

can't read "1": no such variable

The (Tcl) error message is very informative. Tcl feels responsible for substituting a value of a Tcl variable 1 for $1 (meant for awk as part of the awk script). This is due to improper quoting of your awk scriplet. At the same time, you want $b to be substituted for from within Tcl.

Turn awk 'print $1 ~ /^$b/' into awk [string map [list @b@ $b] {{$1 ~ /^@b@/}}]. Curly braces will preclude Tcl substitutions for $1, @b@ will have already been substituted for before awk sees it thanks to [string map].

exec cat cells.txt | awk [string map [list @b@ $b] {{$1 ~ /^@b@/}}]

That written, I fail to see why you are going back and forth between grep, awk etc. and Tcl. All of this could be done in Tcl alone.