user1134991 user1134991 - 3 months ago 18
Linux Question

Tcl exec on grep returns "grep: nothing to repeat", whereas normal LINUX gives right answer

Here is what happens when I run a command using the cshell:

find /projects/corpeng/members/ldagan/adm/utils/Synopsys/CCK/shared_tcl_code -name "*.tcl" | grep -v regression | xargs grep -Plc "^[ ]*namespace[ ]+eval[ ]+DlgViolationKeepProcs "
> /projects/corpeng/members/ldagan/adm/utils/Synopsys/CCK/shared_tcl_code/DlgViolationKeepProcs.tcl


So far, so so good. However, see what happens when I try to do the same in TCL 8.4:

exec find /projects/corpeng/members/ldagan/adm/utils/Synopsys/CCK/shared_tcl_code -name "*.tcl" | grep -v regression | xargs grep -Plc "^[ ]*namespace[ ]+eval[ ]+DlgViolationKeepProcs "
> grep: nothing to repeat


Why? Any ideas?
Thanks.

Answer

The problem is that [] in double-quotes is processed as a Tcl command substitution. In particular, [ ] gets replaced with the empty string, i.e., deleted! The simplest fix is to put the grep term in {braces} to inhibit substitutions, though putting a backslash (\) in front of the [ also works.

Let's make your code a little easier to read too by using some strategic variables:

# Where to search from; often a nice thing to separate out
set basedir /projects/corpeng/members/ldagan/adm/utils/Synopsys/CCK/shared_tcl_code

# What to look for; note the braces!
set term {^[ ]*namespace[ ]+eval[ ]+DlgViolationKeepProcs }

exec find $basedir -name "*.tcl" | grep -v "regression" | xargs grep -Plc $term

It would also work if you'd said:

set term "^\[ ]*namespace\[ ]+eval\[ ]+DlgViolationKeepProcs "

But experience tells me to try to avoid using backslashes more than necessary; they are more confusing in the longer term.