【问题标题】:how to parse a csv file using batch script?如何使用批处理脚本解析 csv 文件?
【发布时间】:2014-02-20 22:26:19
【问题描述】:

我对批处理文件很陌生。 有人可以帮我编写一个批处理脚本来解析如下所示的 csv 文件:

"Expert Info (Chat/Sequence): GET /?password=Katy HTTP/1.1\r\n","Feb 20, 2014 19:34:46.571807000","b5:54:f4:v7:xo:6l"

"Expert Info (Chat/Sequence): GET /?password=Cory HTTP/1.1\r\n","Feb 20, 2014 19:34:51.671167000","b5:54:f4:v7:xo:6l"

"Expert Info (Chat/Sequence): GET /?password=Mike HTTP/1.1\r\n","Feb 20, 2014 19:34:57.145898000","b5:54:f4:v7:xo:6l"

并将其转换为另一个 csv 文件,如下所示:

"Katy", "2014-02-20", "19:34:46", "b5:54:f4:v7:xo:6l" 
"Cory", "2014-02-20", "19:34:51", "b5:54:f4:v7:xo:6l" 
"Mike", "2014-02-20", "19:34:57", "b5:54:f4:v7:xo:6l"

这是我写的:

@echo off
FOR /F "tokens=6,8,9,10,11* delims=,? " %%a in (file.csv) do (

set pass=%%a
set month=%%b
set day=%%c
set year=%%d
set sec=%%e
set mac=%%f
echo "%%a" %%b %%c %%d %%e %%f

if %month:~1,10%==Jan set month=01
if %month:~1,10%==Feb set month=02
if %month:~1,10%==Mar set month=03
if %month:~1,10%==Apr set month=04
if %month:~1,10%==May set month=05
if %month:~1,10%==Jun set month=06
if %month:~1,10%==Jul set month=07
if %month:~1,10%==Aug set month=08
if %month:~1,10%==Sep set month=09
if %month:~1,10%==Oct set month=10
if %month:~1,10%==Nov set month=11
if %month:~1,10%==Dec set month=12

echo "%pass:~9,4%", "%year%-%month:~1,10%-%day%", "%sec:~,8%", %mac% >> text.csv)

【问题讨论】:

  • 看看for 命令——特别是使用/f 开关。您应该在此处发布您在尝试解决问题时遇到的问题,而不是问题本身。
  • 抱歉,刚刚添加了我的代码

标签: batch-file csv for-loop cmd


【解决方案1】:
@ECHO OFF
SETLOCAL
(
FOR /F "tokens=6,8,9,10,11* delims=,? " %%a in (q21921051.txt) do (
 set pass=%%a
 set month=%%b
 set day=%%c
 set year=%%d
 set sec=%%e
 set mac=%%f
 CALL :CALC
)
)> text.csv
GOTO :EOF
:calc

if %month:~1,10%==Jan set month=01
if %month:~1,10%==Feb set month=02
if %month:~1,10%==Mar set month=03
if %month:~1,10%==Apr set month=04
if %month:~1,10%==May set month=05
if %month:~1,10%==Jun set month=06
if %month:~1,10%==Jul set month=07
if %month:~1,10%==Aug set month=08
if %month:~1,10%==Sep set month=09
if %month:~1,10%==Oct set month=10
if %month:~1,10%==Nov set month=11
if %month:~1,10%==Dec set month=12

echo "%pass:~9,4%", "%year%-%month%-%day%", "%sec:~,8%", %mac%

GOTO :eof

我使用了一个名为 q21921051.txt 的文件进行测试。

快到了。您的主要问题是delayed expansion - 在块语句(a parenthesised series of statements) 中,整个块被解析并然后执行。块中的任何%var% 都将替换为该变量的值在解析块时 - 在块执行之前。

因此,IF (something) else (somethingelse) 将在遇到 IF 时使用 %variables% 的值执行 - 这同样适用于 FOR ... DO (block)

解决此问题的两种常见方法是 1) 使用 setlocal enabledelayedexpansion 并使用 !var! 代替 %var% 来访问 var 的更改值或 2) 调用子程序以使用改变了值。

我这里用的是第二种方法

还请注意,(用括号括起整个例程) 将使用重定向器重定向其所有输出 - 在这种情况下为>text.csv如果您希望追加而不是重新创建文件,> 应该是 >>

我不确定%month:~1,10% 的痴迷是什么。批量子串从%var:~m,n%获取,其中,n是可选的; m 是从字符串开始的字符计数,如果为负,则从结尾开始。 ,n 正数 = 返回的最大长度;负数 = 从结尾开始的字符中的结束位置;缺失=在m之后全部返回

因此,由于%month% 将包含"Feb,因此只需要%month:~1% - 但我留下了您的原件。

【讨论】:

    【解决方案2】:

    将一个数据转换为另一个数据(例如将月份名称转换为月份编号)的最简单方法是使用array

    @echo off
    setlocal EnableDelayedExpansion
    
    rem Create the conversion array of month names to month numbers
    set m=100
    for %%a in (Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) do (
       set /A m+=1
       set month["%%a]=!m:~1!
    )
    
    (for /F "tokens=6,9,10,11,12,14 delims==,. " %%a in (file.csv) do (
       echo "%%a", "%%d-!month[%%b]!-%%c", "%%e", %%f
    )) > text.csv
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多