【问题标题】:Reading from a csv file and extracting certain data columns based on first column value从 csv 文件读取并根据第一列值提取某些数据列
【发布时间】:2013-07-04 14:50:44
【问题描述】:

这是我的第一个批处理程序,我一直在网上搜索,但仍在努力编写解决方案。

我有以下 CSV 文件:

"RH",2013/06/15 02:14:58 -0400,"X","LQ3SUEEWPWKL6",005,
"FH",01
"SH",2013/06/14 00:00:00 -0400,2013/06/14 23:59:59 -0400,"LQ3SUEEWPWKL6",""
"CH","TransactionID","InvoiceID", 
......

我正在尝试编写一个简单的程序来执行以下操作:

  • 如果 column1 = "RH",则提取 column2 值 (2013/06/15 02:14:58 -0400)
  • 如果 column1 = "SH",则提取 column4 值 (LQ3SUEEWPWKL6)

并将输出通过管道传输到文件。


这是我目前的代码,但 if 条件对我不起作用

@echo off
:: Set input file in variable
::Set _InputFile=%1

:: Store input line into different variables
FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
Set _var1=%%A
Set _var2=%%B
Set _var3=%%C
Set _var4=%%D
Set _var5=%%E
Set _var6=%%F
Set _var7=%%G
Set _var8=%%H
Set _var9=%%I
Set _var10=%%J
Set _var11=%%K
Set _var12=%%L
Set _var13=%%M
Set _var14=%%N
Set _var15=%%O
Set _var16=%%P
Set _var17=%%Q
Set _var18=%%R


IF "%_var1%"=="RH" echo %var2%

)

我的 CSV 文件在 Excel 和记事本中看起来不错,但是当我执行脚本以显示第一个变量时,看起来第一条记录的“RH”之前有一些垃圾字符 - 我无法绕过它,因为我需要如果 var1 = "RH",则提取额外的列数据:

"RH"
FH
01
SH
CH
TransactionID,PaymentTrackingID,
SF
SF
SC
RF
CAD,CR,0
RF
USD,CR,0
RC
FF

【问题讨论】:

  • 你尝试了什么?你走了多远?
  • 这是我目前所拥有的,但“如果”条件对我不起作用。
  • 你的意思是IF "%_var1%"=="RH" echo %_var2% 吗?我没有看到 var2(即没有前面的“_”)。
  • 这里的tokens=1-18 是什么意思?

标签: windows csv for-loop batch-file cmd


【解决方案1】:

由于“为什么我的行以∩╗┐“RH”开头”没有答案,我会做一些掘墓。

所以,∩╗┐ 来自 BOM(字节顺序标记),表示文件是 UTF 格式,以及字节的写入方式(如有必要)。 答案: 你可以使用

if x%_var1:RH=%x NEQ x%_var1%x (echo %_var2%)

这将检查 RH 是否在 %_var1% 中(如果在 var 中替换 RH 后,它没有改变,RH 不在 var 中) 这意味着,Bom 是否在这里并不重要。但是,如果您想要完全匹配,就会遇到问题。

另一种处理方法是不在文件中包含 bom,这意味着在没有 BOM 的情况下保存为 ASCII 或 UTF-8;或者使用工具从 UTF-8 文件中去除 bom。

【讨论】:

    【解决方案2】:

    您需要启用delayed expansion:

    @echo off
    
    setlocal EnableDelayedExpansion
    
    set "_InputFile=..."
    
    for /f "tokens=1-18* delims=," %%A in (%_InputFile%) do (
      Set _var1=%%A
      Set _var2=%%B
      ...
    
      if "!_var1!"=="RH" echo !_var2!
    )

    【讨论】:

      【解决方案3】:
      (
      FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
        if "%%~A"=="RH" echo %%~B
        if "%%~A"=="SH" echo %%~D
       )
      )>youroutputfilename
      

      应该可以 - 无需将所有值分配给不同的变量 - 但如果您打算使用它们,那么

      FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
      ...
      Set _var17=%%Q
      Set _var18=%%R
      CALL :PROCESS
      )
      ...
      GOTO :EOF
      
      :PROCESS
      IF %_var1%=="RH" echo %_var2%
      IF %_var1%=="SH" echo %_var4%
      GOTO :EOF
      

      请注意,使用此方法时,由于您将 %%x 分配给 _varx,因此如果引用了 %%x,则引号将包含在分配的值中。要删除封闭引号(如果存在),请使用 SET _varx=%%~x


      关于 OP 问题的附录 20130703-1956Z

      @ECHO OFF
      SETLOCAL
      SET _Inputfile=u:\noname1.txt
      (
      FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
        SET "RH="
        SET "SH="
        ECHO(%%A|FINDSTR /l /c:"\"RH\"" >NUL
        IF NOT ERRORLEVEL 1 SET RH=Y
        ECHO(%%A|FINDSTR /l /c:"\"SH\"" >NUL
        IF NOT ERRORLEVEL 1 SET SH=Y
        if DEFINED RH echo %%~B
        if DEFINED SH echo %%~D
       )
      )>u:\youroutputfilename
      TYPE u:\youroutputfilename
      del u:\youroutputfilename
      echo========First way
      
      (
      FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
        SET _var1=%%A
        SET "RH="
        SET "SH="
        CALL :process
        if DEFINED RH echo %%~B
        if DEFINED SH echo %%~D
       )
      )>u:\youroutputfilename
      
      TYPE u:\youroutputfilename
      del u:\youroutputfilename
      echo========Second way
      
      SETLOCAL ENABLEDELAYEDEXPANSION 
      (
      FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
        SET _var1=%%A
        IF "!_var1:~-4!"==""RH"" echo %%~B
        IF "!_var1:~-4!"==""SH"" echo %%~D
       )
      )>u:\youroutputfilename
      
      TYPE u:\youroutputfilename
      del u:\youroutputfilename
      echo========Third way
      ENDLOCAL
      
      GOTO :EOF
      
      :process
      IF "%_var1:~-4%"==""RH"" SET RH=Y
      IF "%_var1:~-4%"==""SH"" SET SH=Y
      GOTO :EOF
      

      【讨论】:

      • 谢谢 - 我选择了您的第一个示例代码,因为它是最简单的。第一条记录在_var1中有垃圾字符,如何摆脱它,因为它没有打印var2
      • 没有真正看到有问题的记录,也没有任何关于垃圾字符是什么的概念,我不知所措。如果它是标题记录,那么在 FOR/f 指令中包含 skip=1 应该忽略该行。另请注意,由于您尚未执行 setlocal,您可能正在处理之前运行的陈旧值 - IF 您正在使用 _var1 - 但我很困惑 - 如果您是使用第一个示例,无论如何都避免了_varx 的设置,为什么_var1 的值应该很重要?还是您指的是数据文件中第一行的第一个元素中的值?
      • 我添加了一些示例数据,这些数据在第一个变量记录上显示了一些不需要的字符。结果,如果第一个变量=“RH”,我的逻辑在我想提取第二个变量的地方不起作用。谢谢。
      【解决方案4】:

      您遇到了解析问题。首先用 ) 结束 for 循环,之后您可以使用新变量:

      @echo off
      :: Set input file in variable
      ::Set _InputFile=%1
      
      :: Store input line into different variables
      FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
          Set "_var1=%%A"
          Set "_var2=%%B"
          Set "_var3=%%C"
          Set "_var4=%%D"
          Set "_var5=%%E"
          Set "_var6=%%F"
          Set "_var7=%%G"
          Set "_var8=%%H"
          Set "_var9=%%I"
          Set "_var10=%%J"
          Set "_var11=%%K"
          Set "_var12=%%L"
          Set "_var13=%%M"
          Set "_var14=%%N"
          Set "_var15=%%O"
          Set "_var16=%%P"
          Set "_var17=%%Q"
          Set "_var18=%%R"
      )
      
      IF "%_var1%"=="RH" echo %var2%
      

      【讨论】:

        猜你喜欢
        • 2020-08-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-14
        • 1970-01-01
        • 2019-08-23
        • 1970-01-01
        • 2021-10-02
        • 1970-01-01
        相关资源
        最近更新 更多