我想我一开始就疯狂地使用批处理文件,但这个问题让我撕裂了我的头发!以下批处理脚本通常可以正常工作。但是,在第一次运行时,它将给出“命令的语法不正确”错误;它将执行此操作,直到我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
时,它就会放弃。
我认为我错过了一些东西......任何想法都可能是什么!? (除了我的弹珠!)
答案 0 :(得分: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
答案 1 :(得分:1)
Stephan是正确的,由于未在 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个或多个空格,则必须用双引号括起所有文件引用,以便为这些文件提供工作代码。