从CSV文件中读取数据,并根据第一列的值提取特定的数据列。

11

这是我的第一个批处理程序,我在网上搜索了很久,但仍然难以编写出一个解决方案。

我有以下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

1
你尝试了什么?你取得了多少进展? - dnet
这是我目前的代码,但是“if”条件对我来说不起作用。 - user2550880
你的意思是 IF "%_var1%"=="RH" echo %_var2% 吗?我没有看到一个 var2(即没有前置下划线)。 - Rapnar
这里的 tokens=1-18 是什么意思? - zygimantus
4个回答

10
(
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。 - user2550880
如果没有实际查看相关记录,也不知道垃圾字符是什么,我就束手无策了。如果这是一个标题记录,那么在 FOR/f 指令中包含 skip=1 应该会忽略该行。请注意,由于您尚未执行 setlocal,因此您可能正在处理来自先前运行的旧值 - 如果 您正在使用 _var1 - 但我感到困惑 - 如果您使用第一个示例,在任何情况下都避免设置 _varx,为什么 _var1 的值会很重要?或者您是指数据文件中第一行的第一个元素的值? - Magoo
我已添加了一些示例数据,显示第一个变量记录上有一些不需要的字符。因此,我的逻辑无法正常工作,如果第一个变量=“RH”,我想要提取第二个变量。谢谢。 - user2550880

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%

3

你需要启用延迟扩展

@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!
)

2

由于“为什么我的行以∩╗┐开头”的问题没有答案,我会进行一些挖掘。

所以,∩╗┐来自BOM(字节顺序标记),它指示文件处于UTF格式,并在必要时写入字节的方式。 关于答案: 您可以使用

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

这将检查RH是否在%_var1%中(如果在替换变量后RH没有改变,那么RH不在变量中),这意味着BOM是否存在并不重要。尽管如此,如果您想要完全匹配,则可能会遇到问题。

另一种处理方法是不将BOM包含在文件中,这意味着以ASCII或UTF-8而不带BOM保存;或使用工具从您的UTF-8文件中剥离BOM。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接