使用批处理文件生成多个Mathematica脚本

时间:2014-01-28 05:50:40

标签: batch-file

希望这不是一个重复的问题;我搜索的结果没有太多(大多数不知道要搜索的术语)。

我目前有一个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)。可能是批处理文件不是要走的路。如果有其他方法可以解决这个问题,我会尝试任何事情。

感谢大家的帮助!

2 个答案:

答案 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_7051,然后,只是因为它可能(不知道你的情况以何种方式)同样为{{{的所有组合构建脚本1}}和(20 to 22 step 1)_(70 to 74 step 2)

似乎为我工作......