2
votes

I want to execute the folowing shell command by tcl :

cat $file_path/file | grep test > $file_path/des_file

I use exec but I got the following error:

cat :|grep No such file or directory

how to make this command works fine with tcl

1
From the error message it looks like the file does not exists in the directory. Check the file's existence. Print the file_path and make sure it is not empty. - Dinesh
please update your Q with the actual tcl exec call. It looks like you may need to add spaces so your cmd looks like a cmd-line invocation, ie. cat /path/to/file | grep ... Also, you can reduce this to grep test /p/2/file > out. Good luck. - shellter

1 Answers

4
votes

I'm betting that you're actually writing this:

cat $file_path/file |grep test > $file_path/des_file

With no space between | and grep. Tcl's exec cares about this since it assembles the pipeline without going to an external shell, and it is rather more finicky about these things.

One of the alternatives, only suitable where you don't have spaces in pathnames, is to do:

# Or however you want to make the script, such as popping up a dialog box in a GUI
set shell_script "cat $file_path/file |grep test > $file_path/des_file"
exec sh -c $shell_script

Though you can do it simply without that cat too:

exec grep test < $file_path/file > $file_path/des_file

That said, since it is grep you can do it entirely in Tcl:

# Read in all the lines
set f [open $file_path/file]
set lines [split [read $f] \n]
close $f

# Filter the lines
set matches [lsearch -all -inline -glob $lines *test*]

# Write out the filtered lines
set f [open $file_path/des_file w]
puts $f [join $matches \n]
close $f

The -regexp option to lsearch is a closer match to what grep does than -glob, but it's slower and overkill for this case.