-1

我想我一开始就很生气地使用批处理文件,但是这个问题让我把头发扯掉了!下面的批处理脚本通常工作得很好。但是,在第一次运行时,它会给出“命令的语法不正确”的错误;它会一直这样做,直到我REM把所有东西都搞定,运行它,然后取消REM它。然后它神奇地再次开始工作!

@echo off

REM Create processed data directory
set "PROCDIR=processed"
mkdir %PROCDIR% 2>nul

REM Loop through CSV files and process them
for %%f in (*.csv) do (
  set "in=%%~nf"
  set "input=%%~nxf"
  set "out_lang=%PROCDIR%\%in%_lang.csv"
  set "out_spr=%PROCDIR%\%in%_spr.csv"
  set "out_ajt=%PROCDIR%\%in%_ajt.csv"

  echo Processing %input%

  REM Split input file appropriately
  REM FIXME Hardcoded line ranges are brittle
  sed -n "1,2p"  %input% > %out_lang%
  sed -n "3,55p" %input% > %out_spr%.tmp
  sed -n "56,$p" %input% > %out_ajt%.tmp

  REM Unpack SPR data
  REM n.b., Needs gawk 4, or later
  gawk -f spr.awk %out_spr%.tmp > %out_spr%
  del %out_spr%.tmp

  REM Substitute AJT data values
  REM n.b., -i seems to be buggy in Windows
  sed -f ajt.sed %out_ajt%.tmp > %out_ajt%
  del %out_ajt%.tmp
)

如果我REM退出@echo off,它似乎失败了,因为变量替换有时 - 由于未知原因 - 不起作用。然后,当它到达时sed,它就放弃了。

我想我错过了一些东西......任何想法可能是什么!?(除了我的弹珠!)

4

2 回答 2

2

如果我可以提供建议,使用和滥用PAUSE命令,ECHO并转义^其中的字符。也可以 Ctrl-C 在PAUSE.

这是一个调试版本:

@echo off

SETLOCAL
REM Create processed data directory
set "PROCDIR=processed"
echo mkdir %PROCDIR% 2^>nul

REM Loop through CSV files and process them
for %%F in (*.csv) do (
  set "in=%%~nF"
  echo in: %in%
  set "input=%%~nxF"
  echo input: %input%
  set "out_lang=%PROCDIR%\%in%_lang.csv"
  set "out_spr=%PROCDIR%\%in%_spr.csv"
  set "out_ajt=%PROCDIR%\%in%_ajt.csv"

  echo Processing %input%
PAUSE

  REM Split input file appropriately
  REM FIXME Hardcoded line ranges are brittle
  echo sed -n "1,2p"  %input% ^> %out_lang%
  echo sed -n "3,55p" %input% ^> %out_spr%.tmp
  echo sed -n "56,$p" %input% ^> %out_ajt%.tmp
PAUSE

  REM Unpack SPR data
  REM n.b., Needs gawk 4, or later
  echo gawk -f spr.awk %out_spr%.tmp ^> %out_spr%
  echo del %out_spr%.tmp
PAUSE

  REM Substitute AJT data values
  REM n.b., -i seems to be buggy in Windows
  echo sed -f ajt.sed %out_ajt%.tmp ^> %out_ajt%
  echo del %out_ajt%.tmp
PAUSE

)
ENDLOCAL
GOTO :EOF
EXIT /B 0

我补充说setlocal enabledelayedexpansion,这似乎解决了未声明的变量错误。

这是一个工作版本(您必须删除所有冗余echo和插入符号^):

@echo off
setlocal enabledelayedexpansion

REM Create processed data directory
set "PROCDIR=processed"
echo mkdir %PROCDIR% 2^>nul

REM Loop through CSV files and process them
for %%F in (*.csv) do (
  set "in=%%~nF"
  echo in: !in!
  set "input=%%~nxF"
  echo input: !input!
  set "out_lang=!PROCDIR!\!in!_lang.csv"
  set "out_spr=!PROCDIR!\!in!_spr.csv"
  set "out_ajt=!PROCDIR!\!in!_ajt.csv"

  echo Processing !input!
PAUSE

  REM Split input file appropriately
  REM FIXME Hardcoded line ranges are brittle
  echo sed -n "1,2p"  !input! ^> !out_lang!
  echo sed -n "3,55p" !input! ^> !out_spr!.tmp
  echo sed -n "56,$p" !input! ^> !out_ajt!.tmp
PAUSE

  REM Unpack SPR data
  REM n.b., Needs gawk 4, or later
  echo gawk -f spr.awk !out_spr!.tmp ^> !out_spr!
  echo del !out_spr!.tmp
PAUSE

  REM Substitute AJT data values
  REM n.b., -i seems to be buggy in Windows
  echo sed -f ajt.sed !out_ajt!.tmp ^> !out_ajt!
  echo del !out_ajt!.tmp
PAUSE

)
endlocal
GOTO :EOF
EXIT /B 0
于 2015-09-11T23:13:30.790 回答
1

斯蒂芬是对的,批处理代码不起作用,因为没有在FOR循环中使用延迟扩展。

@echo off
setlocal EnableDelayedExpansion
REM Create processed data directory
set "PROCDIR=processed"
mkdir "%PROCDIR%" 2>nul

REM Loop through CSV files and process them
for %%f in (*.csv) do (
  set "in=%%~nf"
  set "input=%%~nxf"
  set "out_lang=%PROCDIR%\!in!_lang.csv"
  set "out_spr=%PROCDIR%\!in!_spr.csv"
  set "out_ajt=%PROCDIR%\!in!_ajt.csv"

  echo Processing !input!

  REM Split input file appropriately
  REM FIXME Hardcoded line ranges are brittle
  sed -n "1,2p"  "!input!" >"!out_lang!"
  sed -n "3,55p" "!input!" >"!out_spr!.tmp"
  sed -n "56,$p" "!input!" >"!out_ajt!.tmp"

  REM Unpack SPR data
  REM n.b., Needs gawk 4, or later
  gawk -f spr.awk "!out_spr!.tmp" >"!out_spr!"
  del "!out_spr!.tmp"

  REM Substitute AJT data values
  REM n.b., -i seems to be buggy in Windows
  sed -f ajt.sed "!out_ajt!.tmp" >"!out_ajt!"
  del "!out_ajt!.tmp"
)
endlocal

(由...定义的块中引用的每个环境变量都已)在解析整个块时由命令处理器扩展。在执行时输出到命令提示符窗口的帮助页面if /?之一详细解释了这一点。

这可以在没有从命令提示符窗口中运行第一行的情况下运行有问题的批处理代码时看到。在命令提示符窗口中运行批处理文件(不带echo off或不带echo on)应该用于调试未按预期工作的批处理代码。

如果当前目录中的任何 CSV 文件在文件名中包含 1 个或多个空格,则必须将所有文件引用括在双引号中,以便这些文件也具有工作代码。

于 2015-09-12T11:50:01.957 回答