What you do is very complex: you have an input file, a set of search/replace rules, and produce some output. The rules, however, require calling expr
.
Here is a made-up data file (data.txt):
lane_out[0][7] = "foo bar"
lane_out[1][0] = "foo bar"
lane_out[1][1] = "foo bar"
lane_out[2][0] = "foo bar"
lane_out[2][1] = "foo bar"
And the rules file (rules.txt):
{\[(\d+)\]\[(\d+)\]} {\[[expr {\1 * 8 + \2}]\]}
Here is my script (search_replace.tcl):
package require Tclx
# Read the rules file
set rules {}
for_file line rules.txt {
lassign $line find replace
lappend rules $find $replace
}
# Read the data, apply rules
for_file line data.txt {
foreach {find replace} $rules {
regsub -all $find $line $replace line
set line [subst $line]
puts $line
}
}
Output:
lane_out[7] = "foo bar"
lane_out[8] = "foo bar"
lane_out[9] = "foo bar"
lane_out[16] = "foo bar"
lane_out[17] = "foo bar"
Discussion
- The rules.txt's format: each line contains search- and replace expressions, separated by a space
The code will translate a line such as
lane_out[2][1] = "foo bar"
to:
lane_out\[[expr {2 * 8 + 1}]\] = "foo bar"
Then, the
subst
command replaces that with:lane_out[17] = "foo bar"
The tricky part is to escape the square brackets so that
expr
can do the right thing.