我正在尝试将Linux bash脚本转换为其Windows计数器部分 这是实际的bash脚本:
#!/bin/bash
# Usage parse_log.sh caffe.log
# It creates the following two text files, each containing a table:
# caffe.log.test (columns: '#Iters Seconds TestAccuracy TestLoss')
# caffe.log.train (columns: '#Iters Seconds TrainingLoss LearningRate')
# get the dirname of the script
DIR="$( cd "$(dirname "$0")" ; pwd -P )"
if [ "$#" -lt 1 ]
then
echo "Usage parse_log.sh /path/to/your.log"
exit
fi
LOG=`basename $1`
sed -n '/Iteration .* Testing net/,/Iteration *. loss/p' $1 > aux.txt
sed -i '/Waiting for data/d' aux.txt
sed -i '/prefetch queue empty/d' aux.txt
sed -i '/Iteration .* loss/d' aux.txt
sed -i '/Iteration .* lr/d' aux.txt
sed -i '/Train net/d' aux.txt
grep 'Iteration ' aux.txt | sed 's/.*Iteration \([[:digit:]]*\).*/\1/g' > aux0.txt
grep 'Test net output #0' aux.txt | awk '{print $11}' > aux1.txt
grep 'Test net output #1' aux.txt | awk '{print $11}' > aux2.txt
# Extracting elapsed seconds
# For extraction of time since this line contains the start time
grep '] Solving ' $1 > aux3.txt
grep 'Testing net' $1 >> aux3.txt
$DIR/extract_seconds.py aux3.txt aux4.txt
# Generating
echo '#Iters Seconds TestAccuracy TestLoss'> $LOG.test
paste aux0.txt aux4.txt aux1.txt aux2.txt | column -t >> $LOG.test
rm aux.txt aux0.txt aux1.txt aux2.txt aux3.txt aux4.txt
# For extraction of time since this line contains the start time
grep '] Solving ' $1 > aux.txt
grep ', loss = ' $1 >> aux.txt
grep 'Iteration ' aux.txt | sed 's/.*Iteration \([[:digit:]]*\).*/\1/g' > aux0.txt
grep ', loss = ' $1 | awk '{print $9}' > aux1.txt
grep ', lr = ' $1 | awk '{print $9}' > aux2.txt
# Extracting elapsed seconds
$DIR/extract_seconds.py aux.txt aux3.txt
# Generating
echo '#Iters Seconds TrainingLoss LearningRate'> $LOG.train
paste aux0.txt aux3.txt aux1.txt aux2.txt | column -t >> $LOG.train
rm aux.txt aux0.txt aux1.txt aux2.txt aux3.txt
这是我的转换版本:
ECHO OFF
REM Usage parse_log.sh caffe.log
REM It creates the following two text files, each containing a table:
REM caffe.log.test (columns: '#Iters Seconds TestAccuracy TestLoss')
REM caffe.log.train (columns: '#Iters Seconds TrainingLoss LearningRate')
SET sed="tools/3rdparty/bin/sed.exe"
SET awk="tools/3rdparty/bin/awk.exe"
SET grep="tools/3rdparty/bin/grep.exe"
SET rm="tools/3rdparty/bin/rm.exe"
SET paste="tools/3rdparty/bin/paste.exe"
REM get the dirname of the script
SET DIR=%~dp0
IF [%1]==[] (
ECHO "Usage parse_log.bat path\to\your.log"
EXIT
)
SET LOG="basename %~n1"
ECHO "Dir = %DIR%"
ECHO "LOG = %LOG%"
%sed% -n "/Iteration .* Testing net/,/Iteration *. loss/p" %1 > aux.txt
%sed% -i "/Waiting for data/d" aux.txt
%sed% -i "/prefetch queue empty/d" aux.txt
%sed% -i "/Iteration .* loss/d" aux.txt
%sed% -i "/Iteration .* lr/d" aux.txt
%sed% -i "/Train net/d" aux.txt
%grep% "Iteration " aux.txt | %sed% "s/.*Iteration \([[:digit:]]*\).*/\1/g" > aux0.txt
%grep% "Test net output #0" aux.txt | %awk% "{print %11}" > aux1.txt
%grep% "Test net output #1" aux.txt | %awk% "{print %11}" > aux2.txt
REM Extracting elapsed seconds
REM For extraction of time since this line contains the start time
%grep% "] Solving " %1 > aux3.txt
%grep% "Testing net" %1 >> aux3.txt
%DIR%/extract_seconds.py aux3.txt aux4.txt
REM Generating
ECHO "#Iters Seconds TestAccuracy TestLoss"> %LOG%.test
%paste% aux0.txt aux4.txt aux1.txt aux2.txt | column -t >> %LOG%.test
%rm% aux.txt aux0.txt aux1.txt aux2.txt aux3.txt aux4.txt
REM For extraction of time since this line contains the start time
%grep% "] Solving " %1 > aux.txt
%grep% ", loss = " %1 >> aux.txt
%grep% "Iteration " aux.txt | %sed% "s/.*Iteration \([[:digit:]]*\).*/\1/g" > aux0.txt
%grep% ", loss = " %1 | %awk% "{print %9}" > aux1.txt
%grep% ", lr = " %1 | %awk% "{print %9}" > aux2.txt
REM Extracting elapsed seconds
%DIR%/extract_seconds.py aux.txt aux3.txt
REM Generating
ECHO "#Iters Seconds TrainingLoss LearningRate"> %LOG%.train
%paste% aux0.txt aux3.txt aux1.txt aux2.txt | column -t >> %LOG%.train
%rm% aux.txt aux0.txt aux1.txt aux2.txt aux3.txt
问题首先是我不知道这是否是正确的转换,并且完全符合bash脚本的功能。第二,当我运行脚本时,光标到达时会开始闪烁(等待)
ECHO "LOG = %LOG%"
部分,经过很长一段时间后,它会打印以下内容:
tools/3rdparty/bin/sed.exe: couldn't edit aux.txt: is a terminal
tools/3rdparty/bin/sed.exe: couldn't edit aux.txt: is a terminal
tools/3rdparty/bin/sed.exe: couldn't edit aux.txt: is a terminal
tools/3rdparty/bin/sed.exe: couldn't edit aux.txt: is a terminal
tools/3rdparty/bin/sed.exe: couldn't edit aux.txt: is a terminal
它又等了!
这里有什么问题?
将aux.txt
更改为auxx.txt
后,第一个错误就解决了。但现在我收到了这些错误:
awk: {print examples\cifar10\caffe.log1}
awk: ^ backslash not last character on line
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
awk: {print examples\cifar10\caffe.log1}
awk: ^ backslash not last character on line
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
tools/3rdparty/bin/grep.exe: writing output: Invalid argument
Usage: ./extract_seconds input_file output_file
'column' is not recognized as an internal or external command,
operable program or batch file.
答案 0 :(得分:2)
AUX
是保留字,请参阅Naming Files, Paths, and Namespaces:
请勿对文件名使用以下保留名称:
CON,PRN,AUX,NUL,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8, COM9,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8和LPT9。也 避免这些名称紧跟延期;例如, 不建议
NUL.txt
。有关详细信息,请参阅Namespaces。
请改用其他名称,例如auxx.txt
。
答案 1 :(得分:1)
请阅读How to set environment variables with spaces?和Why is no string output with 'echo %var%' after using 'set var = text' on command line?上的答案,因为您很可能不知道如何定义空格正确的变量值。
不要使用IF [%1]==[]
因为方括号在 IF 上的Windows命令脚本中没有特殊含义,因此批处理可能因语法错误而退出,其中左值包含1或更多的空间。请改为使用IF "%~1"==""
并在命令提示符窗口call /?
中执行,以获取%~1
的解释(第一个参数包含已删除的双引号)。
建议始终使用%~1
,%~2
,...将这些参数引用显式嵌入双引号中。
在Windows上,目录分隔符是反斜杠\
字符,而不是正斜杠/
字符。 Windows命令处理器会在检测到它时自动纠正这个经常出错的错误,但它无法在所有情况下自动检测并纠正/
。
awk 来自* nix并给出反斜杠与Windows命令处理器完全不同的含义。我没有使用 awk 的经验,但我认为最好在Windows上指定带有作为参数传递给 awk 的路径的文件名,并使用正斜杠作为目录分隔符而不是反斜杠。因此我建议更换这些行:
SET awk="tools/3rdparty/bin/awk.exe"
SET grep="tools/3rdparty/bin/grep.exe"
rem Other lines of your batch file.
%grep% "Test net output #0" auxx.txt | %awk% "{print %11}" > aux1.txt
%grep% "Test net output #1" auxx.txt | %awk% "{print %11}" > aux2.txt
通过
set "awk=tools\3rdparty\bin\awk.exe"
set "grep=tools\3rdparty\bin\grep.exe"
rem Other lines of your batch file.
set "LogFileName=%~11"
set "LogFileName=%LogFileName:\=/%"
"%grep%" "Test net output #0" auxx.txt | "%awk%" "{print %LogFileName%}" > aux1.txt
"%grep%" "Test net output #1" auxx.txt | "%awk%" "{print %LogFileName%}" > aux2.txt
在Windows上使用* nix工具需要考虑Windows本机命令行工具(如cmd.exe
)解释的内容以及* {nix}工具(如awk.exe
和grep.exe
所解释的内容)正确的参数语法。
set "LogFileName=%LogFileName:\=/%"
使用相对路径用日志文件名中的正斜杠替换所有反斜杠。在命令提示符窗口set /?
中运行并阅读所有输出帮助页面,以获取有关环境变量值中字符串替换/替换的详细信息。
并在线
%paste% aux0.txt aux3.txt aux1.txt aux2.txt | column -t >> %LOG%.train
Windows命令处理器(cmd.exe
)找不到具有在当前目录中的环境变量column
中定义的文件扩展名的应用程序PATHEXT
或在环境变量{{中定义的任何目录中1}}。此应用程序还必须使用文件扩展名和(相对)路径指定。