希望这不是一个重复的问题;我搜索的结果没有太多(大多数不知道要搜索的术语)。
我目前有一个mathematica脚本,它打开一个数据文件并在其上运行一系列命令。在脚本中,我必须为每个数据文件编辑某些值,例如,analyze_20_70.m可能会读取:
(* ::Package:: *)
Clear[NN, TxyzAll, q, Txyz, twospace, dps, threespace, threeclosed, plane]
datChoice = ReadList[
"/n/homeserver2/user2a/scallion/mathematica/20_70.dat", {Number, Number, Number}];
NN = 51;
% LOTS OF CODE HERE
Export[
"/n/homeserver2/user2a/scallion/mathematica/20_70_time.txt",
time];
Exit[]
因此,为我想要运行的每个文件编辑它是低效的。我一般都是脚本编写新手,但我认为我可以使用批处理脚本来自动执行此过程(即脚本1读取20_70.dat,NN = 51,脚本2读取20_75.dat,NN = 56,脚本3读取20_80。 dat,NN = 61等)
到目前为止,我拼凑了这样的东西:
@echo off
set "begin=20"
set "end=150"
set "count=70"
:LOOP
if %count% GTR %end% (goto END)
(
echo (* ::Package:: *)
echo Clear[NN, TxyzAll, q, Txyz, twospace, dps, threespace, threeclosed, plane]
echo datChoice = ReadList[
echo "/n/homeserver2/user2a/scallion/mathematica/20_70.dat", {Number, Number, Number}];
echo NN = 51;
echo Exit[]
) > testfile_%begin%.txt
set /a count+=5
goto LOOP
:END
(理想情况下,20_70.dat会变成%begin%_%count%.dat)。
如果我用简单的东西替换中间,比如echo hello world> testfile_%begin%.txt,我没问题。但是,尝试打印整个mathematica脚本似乎很乱,我不知道生成的文件中是否会出现换行问题/隐藏字符。因此,我的问题:
1)。是否有更好的方法来打印多行而不是在每行前面放置回声?如果是这样,我会保留使用计数器更改文件名的能力吗?
2)。我的代码自然有()[]; =和其他保留字符无处不在,所以我似乎要把每一行放在引号中(在这种情况下我不能删除引号),或者手动转义每一次违规。我可以通过这样做,但想知道是否有更好的方法。
3)。可能是批处理文件不是要走的路。如果有其他方法可以解决这个问题,我会尝试任何事情。
感谢大家的帮助!
答案 0 :(得分:0)
1)命令echo
将脚本内容中的文本打印到文件(当然包括stdout
)。我建议也使用type
来复制另一个文件中的文本,在这种情况下,你不需要处理特殊字符。所以我会写这样的东西:
type static_begin.txt > output.txt
echo A %dynamic% part >> output.txt
type static_end.txt >> output.txt
它只是复制静态(不变)的开始和结束,并允许在它们之间放置不同的东西。运算符>>
表示附加到文件末尾。
2)您可以使用^
escape批处理文件的特殊字符,例如^(
。
答案 1 :(得分:0)
@ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET "destdir=c:\destdir"
SET "skeleton=%~1"
SET /a count=0
FOR /f "usebackqdelims=" %%S IN ("%~2") DO (
CALL :genscript %%S
)
GOTO :EOF
:genscript
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
SET /a paramcount=1
:paramloop
SET "$%paramcount%=%1"
IF DEFINED $%paramcount% SET /a paramcount+=1&shift&GOTO paramloop
SET /a paramcount -=1
:: Now have $1=1st param, $2=second, etc.
:: Simple substitution : only 2 parameters (dat and NN)
IF DEFINED $3 GOTO loopy
CALL :genfile %$1% %$2%
GOTO :eof
:: We have more than two parameters in the data line.
:: Let's define params as %1=start, %2=incr, %3=end for first item
:: %4=start, %5=incr, %6=end for second item
:: %7=start, %8=incr, %9=end for third item
:: how it's done - up to the user
:loopy
FOR /L %%a IN (%$1% %$2% %$3%) DO (
FOR /L %%b IN (%$4% %$5% %$6%) DO (
FOR /L %%c IN (%$7% %$8% %$9%) DO (
CALL :genfile %%a_%%b %%c
)
)
)
GOTO :eof
:genfile
SET "$batchline1= "/n/homeserver2/user2a/scallion/mathematica/%1.dat", {Number, Number, Number}];"
SET "$batchline2=NN = %2;"
SET "$batchline3= "/n/homeserver2/user2a/scallion/mathematica/%1_time.txt","
SET /a count+=1
SET outscript=script%count%.m
(
FOR /f "tokens=1*delims=:" %%L IN ('FINDSTR /n /r "$" "%skeleton%"') DO (
SET "line=%%M"
CALL :subs
IF DEFINED line ECHO(%%M
)
)>"%destdir%\%outscript%"
GOTO :eof
:: Do the substitution
:subs
:: if LINE is not defined, empty line
IF NOT DEFINED line SET line=Y&GOTO :EOF
SET "line=%line:"=%"
SET "line=%line:&=%"
SET "line=%line:)=%"
SET "line=%line:(=%"
FOR /f "tokens=1*delims==" %%s IN ('set $batch') DO IF "%%s"=="$%line%" (
SET "line="
ECHO(%%t
GOTO :eof
)
GOTO :eof
我相信这会奏效。
以thisbatch skeleton.txt controlfile.txt
skeleton.txt在哪里
(* ::Package:: *)
Clear[NN, TxyzAll, q, Txyz, twospace, dps, threespace, threeclosed, plane]
datChoice = ReadList[
batchline1
batchline2
% LOTS OF CODE HERE
Export[
batchline3
time];
Exit[]
即原始的.m文件,变量行被batchline1..3
替换,这些行由脚本构建并替换。
controlfile.txt是
20_70 51
20 1 22 70 2 74 51 5 66
将从骨架构建脚本,战略性地替换20_70
和51
,然后,只是因为它可能(不知道你的情况以何种方式)同样为{{{的所有组合构建脚本1}}和(20 to 22 step 1)_(70 to 74 step 2)
似乎为我工作......