我有
的C档C:\ SVN \代码\ fileio.c
这将读取2个音频文件
tuningFile = fopen("../../simulation/micdata.bin", "rb");
mic1File = fopen("../../simulation/mic1.pcm", "rb");
我需要编写将读取C文件的TCL脚本代码,并将这两种情况替换为
tuningFile = fopen("C:/SVN/simulation/micdata.bin", "rb");
mic1File = fopen("C:/SVN/simulation/mic1.pcm", "rb");
任何人都可以为下面的内容提供一个紧凑的例子:
感谢
sedy
答案 0 :(得分:2)
关键是你真的要替换:
fopen("../../simulation/
与
fopen("C:/SVN/simulation/
使用string map
轻松完成。其余的问题只是执行文件I / O,而且几乎可以由普通编译器编译的任何 C源文件最好通过将它们全部加载到内存来处理一旦:
set filename {C:\SVN\Code\fileio.c}
set mapping [list {fopen("../../simulation/} {fopen("C:/SVN/simulation/}]
# Slurp the file in
set f [open $filename]
set data [read $f]
close $f
# Apply the mapping
set data [string map $mapping $data]
# Make the original a backup
file rename $filename $filename.bak
# Write back with a separate open
set f [open $filename w]
puts -nonewline $f $data
close $f
如果您愿意,可以使用[lindex $argv 0]
获取文件名作为参数。其余的代码并不关心。
答案 1 :(得分:1)
package require fileutil
set filename C:/SVN/Code/fileio.c
set mapping [list {fopen("../../simulation/} {fopen("C:/SVN/simulation/}]
proc replace {mapping data} {
string map $mapping $data
}
::fileutil::updateInPlace $filename [list replace $mapping]
也应该工作。 (来自Donal的mapping
的定义。)updateInPlace
在其第二个参数中调用命令前缀,将文件的内容传递给该命令,并使用命令的结果更新文件。
这与Donal的答案几乎相同,用更高级别的代码表示。如果您需要备份副本,请在致电updateInPlace
之前执行此操作:
file copy $filename [file rootname $filename].bak
答案 2 :(得分:1)
这是一个提取文件名并在其上使用file normalize
的版本:
set f [open $filename r]
set code [read $f]
close $f
set code [subst -novar -noback [regsub -all {((?:tuningFile|mic1File) = fopen\(")([^"]+)} $code {\1[file normalize "\2"]}]]
打破它,
此命令
regsub -all {((?:tuningFile|mic1File) = fopen\(")([^"]+)} $code {\1[file normalize "\2"]}
将找到字符串tuningFile = fopen("../relative/file
(或“mic1file = ...”)并将其替换为文本
tuningFile = fopen("[file normalize "../relative/file"]
然后我们将其提供给subst
,以便替换嵌入式命令,执行file normalize
命令,从而生成文本
tuningFile = fopen("/full/path/to/file
在C代码中取2:句柄括号
$ pwd
/home/jackman/tmp/base/SVN/Code
$ tree ../..
../..
├── SVN
│ └── Code
│ ├── fileio.c
│ └── normalize.tcl
└── simulation
├── mic1.pcm
└── micdata.bin
3 directories, 4 files
$ cat fileio.c
int tuningFix[MAXTUNING];
tuningFile = fopen("../../simulation/micdata.bin", "rb");
mic1File = fopen("../../simulation/mic1.pcm", "rb");
$ cat normalize.tcl
#! tclsh
package require fileutil
set code [fileutil::cat [lindex $argv 0]]
# protect existing brackets
set bracketmap [list \[ \x01 \] \x02]
set code [string map $bracketmap $code]
# normalize filenames
set code [
subst -novar -noback [
regsub -all {((?:tuningFile|mic1File) = fopen\(")([^"]+)} $code {\1[file normalize "\2"]}
]
]
# restore brackets
set code [string map [lreverse $bracketmap] $code]
puts $code
$ tclsh normalize.tcl fileio.c
int tuningFix[MAXTUNING];
tuningFile = fopen("/home/jackman/tmp/base/simulation/micdata.bin", "rb");
mic1File = fopen("/home/jackman/tmp/base/simulation/mic1.pcm", "rb");
答案 3 :(得分:0)
基于所有评论用户的大力帮助,我能够完成任务
proc replaceFileTemp {} {
global pth_fileio_orig
# create backup for copy back
set pth_backup [file rootname $pth_fileio_orig].bak
file copy $pth_fileio_orig $pth_backup
#get current file path
set thisFilePth [ dict get [ info frame [ info frame ] ] file ]
# get folder for current file
set thisFileFolderPth [file dirname $thisFilePth]
# set the replacement string/path
set replacementPth [file dirname $thisFileFolderPth]
# obtain original string to be replaced
set origPth "../../simulation/toplevel"
# download package for file manipulation
package require fileutil
set mapping [list $origPth $replacementPth]
proc replace {mapping data} {
string map $mapping $data
}
# replace original string with replacement string for all occurrences in file
::fileutil::updateInPlace $pth_fileio_orig [list replace $mapping]
}
# set the path to toplevel C file
set pth_fileio_orig [file normalize "../../../fileio.c"]
replaceFileTemp