0
votes

I have the following TCL script which executes a Linux command to format a file.

exec sed -r '2,$s/(.{55} )/\1\n\t/g' $formatfileName | sed 's/ $//' > $formatfileName

I get an error saying can't read "s": no such variable while executing the above line - It is considering $ sign in Linux command as a variable. I tried to put curly braces {} but that did not work.

Can you please advise how to use the above command without errors? Thanks for your help.

1

1 Answers

2
votes

The issue is that Tcl doesn't use single quotes; the equivalent in Tcl is curly braces (except those nest properly). Also, you need to write to a different file than the one you read in or you get some awkward race conditions between when various bits open the file for reading and for writing that will wipe your file out. (You can rename afterwards.) Something like this should work.

exec sed -r {2,$s/(.{55} )/\1\n\t/g} $formatfileName | sed {s/ $//} > $formatfileName.new
file rename -force $formatfileName.new $formatfileName

That said, I'd be strongly tempted to do this in pure Tcl (longer, but now portable):

set f [open $formatfileName]
set lines [split [read $f] "\n"]
close $f

set f [open $formatfileName "w"]
foreach line $lines {
    # First line is special
    if {[incr LN] == 1} {
        puts $f [string trimright $line]
        continue
    }
    foreach l [split [regsub {.{55} } $line "&\n\t"] "\n"] {
        puts $f [string trimright $l]
    }
}
close $f

The string trimrights are effectively doing what the second sed was doing, and the regsub in the middle is recognisably similar to the first sed, though I'm using an inner split there too so that the trimming can be applied consistently.

There's no tricky file rename here; the read is definitely preceding the write.