Windows Batch 读取文件并将行解析为标记和变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17453085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 10:39:04  来源:igfitidea点击:

Windows Batch to read file and parse lines into tokens and variables

windowsvariablesbatch-filetokenoutput

提问by SonicGoose

I've made a good deal of headway by searching this site and learning the ridiculous language that is Windows batch scripting, but I'm now at a point where I'm stuck. I have a text file with a variable number of lines, each of which looks something like:

通过搜索此站点并学习 Windows 批处理脚本这一荒谬的语言,我取得了很大进展,但我现在陷入了困境。我有一个行数可变的文本文件,每行看起来像:

AA8315,"United States",N777AN,"American Airlines",AAL98,B772,"Boeing 777-223",AAL,"2013-06-11 23:30:47.923","2013-06-12 00:01:14.459"

My batch file:

我的批处理文件:

set THEDATE=2013-06-12
set THEDATABASE=c:\Kinetic\BaseStation\Basestation.sqb
set THECSVFILE=c:\Flights.csv
set THEOUTPUTFILE=c:\FlightsNew.csv
set THISLINE=""

if exist %THECSVFILE% del %THECSVFILE%
if exist %THEOUTPUTFILE% del %THEOUTPUTFILE%

:: allow time for the csv file to be deleted
timeout /t 2 /nobreak

c:\sqlite3.exe -header -csv %THEDATABASE% "select Aircraft.ModeS, Aircraft.ModeSCountry as Country, Aircraft.Registration as Reg, Aircraft.RegisteredOwners as Owner, Flights.Callsign, Aircraft.ICAOTypeCode as Type, Aircraft.Type as Model, Aircraft.OperatorFlagCode as 'Op Flag', Flights.StartTime as 'First Seen', Flights.EndTime as 'Last Seen' from Aircraft INNER JOIN Flights ON (Aircraft.AircraftID=Flights.AircraftID) where Flights.EndTime like '%THEDATE% %%' order by Flights.EndTime DESC;" >> %THECSVFILE%

::allow time for the csv to be written to file
timeout /t 5 /nobreak

::read %THECSVFILE% and loop through each line
for /F "usebackq tokens=* delims=" %%A in (%THECSVFILE%) do (
    set the_line=%%A
    call :process_line
)

:process_line
for /F "usebackq tokens=1,2,3,4,5,6,7,8,9,10 delims=[,]" %%1 in (%the_line%) do (
    set hexcode=%%1
    set country=%%2
    set reg=%%3
    set owner=%%4
    set callsign=%%5
    set planetype=%%6
    set model=%%7
    set opflag=%%8
    set firstseen=%%9
    set lastseen=%%10
    set THISLINE=%hexcode%,%country%,%reg%,%owner%,%callsign%,%planetype%,%model%,%opflag%,%firstseen%,%lastseen%
    echo %THISLINE% > %THEOUTPUTFILE%
)

(I'm assigning the tokens to variables because I will be doing additional validation and formatting of them later. I need to get this part working first!)

(我将标记分配给变量,因为我稍后会对其进行额外的验证和格式化。我需要先让这部分工作!)

When executed, the script does indeed loop through each line of the file, however it does not seem to be assigning %%1to the variable hexcode.

执行时,脚本确实会遍历文件的每一行,但它似乎没有分配%%1给变量hexcode.

The output of the executed command looks like this:

执行命令的输出如下所示:

C:\>for /F "usebackq tokens=1,2,3,4,5,6,7,8,9,10 delims=[,]" %1 in (AA8315 "United States" N777AN "American Airlines" AAL98 B772 "Boeing 777-223" AAL "2013-06-11 23:30:47.923" "2013-06-12 00:01:14.459") do (
set hexcode=%1
 set country=%2
 set reg=%3
 set owner=%4
 set callsign=%5
 set planetype=%6
 set model=%7
 set opflag=%8
 set firstseen=%9
 set lastseen=%10
 set THISLINE=,"United States" ,N807FD ,"Fedex Express" ,FDX1378 ,,"Airbus A310-324" ,FDX ,"2013-06-12 22:56:54.639" ,"2013-06-12 23:05:31.822"
 echo ""  1>c:\FlightsNew.csv
)
The system cannot find the file AA8315.

Any help is greatly appreciated!

任何帮助是极大的赞赏!

采纳答案by James L.

I have always had problems with comma separated values in a forloop. Here's what I did to make your code work.

我总是在for循环中遇到逗号分隔值的问题。这是我为使您的代码正常工作所做的工作。

Test.txt

测试.txt

AA8315,"United States",N777AN,"American Airlines",AAL98,B772,"Boeing 777-223",AAL,"2013-06-11 23:30:47.923","2013-06-12 00:01:14.459"

BatchFile.bat

批处理文件

set THECSVFILE=test.txt

::read %THECSVFILE% and loop through each line
for /F "usebackq tokens=* delims=" %%A in (%THECSVFILE%) do (
    set the_line=%%A
    call :process_line
)
goto TheEnd

:process_line
for /F "usebackq tokens=1,2,3,4,5,6,7,8,9,10 delims=~" %%1 in ('%the_line:,=~%') do (
    set hexcode=%%1
    set country=%%2
    set reg=%%3
    set owner=%%4
    set callsign=%%5
    set planetype=%%6
    set model=%%7
    set opflag=%%8
    set firstseen=%%9
    set lastseen=%%10
    set THISLINE=%hexcode%,%country%,%reg%,%owner%,%callsign%,%planetype%,%model%,%opflag%,%firstseen%,%lastseen%
    echo %THISLINE% > %THEOUTPUTFILE%
)

:TheEnd

Notice the :process_lineforloop. I had to add single quotes around the %the_line%so it didn't try to interpret the string as a filename. Then I replaced all commas with the ~ character, and used the ~ character as the delimiter. It may not work precisely with all your data (if it contains single quotes or the ~ character), but it does work with this one record and gets you moving in the right direction again.

注意:process_linefor循环。我不得不在周围添加单引号,%the_line%因此它不会尝试将字符串解释为文件名。然后我用 ~ 字符替换了所有逗号,并使用 ~ 字符作为分隔符。它可能不适用于您的所有数据(如果它包含单引号或 ~ 字符),但它确实适用于这条记录,并让您再次朝着正确的方向前进。

回答by Endoro

this works here:

这在这里工作:

    for /f "tokens=1-10delims=," %%a in ("AA8315,"United States",N777AN,"American Airlines",AAL98,B772,"Boeing 777-223",AAL,"2013-06-11 23:30:47.923","2013-06-12 00:01:14.459"") do (
     set hexcode=%%a
     set country=%%b
     set reg=%%c
     set owner=%%d
     set callsegn=%%e
     set planefype=%%f
     set model=%%g
     set opflag=%%h
     set firstseen=%%i
     set lastseen=%%j
     set THISLINE=%%a,%%b,%%c,%%d,%%e,%%f,%%g,%%h,%%i,%%j
    )
    >"c:\FlightsNew.csv" echo %THISLINE%

I'm not sure, why you need the tokens.

我不确定,为什么你需要令牌。

回答by Magoo

You can only use letters fro the metavariable (%%1in your code) - but the lower-case and upper-case letters are distinct.

您只能使用元变量中的字母(%%1在您的代码中) - 但小写和大写字母是不同的。

Yes, you can use some other characters, but the contiguous blocks avaliable for "tokens=1-10"(which is an easier version of 1,2,3...) are a..z and A..Z

是的,您可以使用其他一些字符,但可用的连续块"tokens=1-10"(这是 1,2,3... 的更简单版本)是 a..z 和 A..Z

%0..%9 are reserved for the parameters to the batch or batch-procedure.

%0..%9 保留用于批处理或批处理过程的参数。