批处理文件:从 .csv 文件中读取浮点值

Posted

技术标签:

【中文标题】批处理文件:从 .csv 文件中读取浮点值【英文标题】:Batch File: Reading Floating Point Values from a .csv file 【发布时间】:2020-12-08 01:03:47 【问题描述】:

我制作了一个读取 .csv 文件的批处理文件。然后它继续从特定列(在本例中为第 4 列)中获取值并找到最高值。该脚本可以很好地处理整数,但是一旦我尝试传入具有浮点数的 .csv 文件,该脚本只会读取第一个数字。即,1.546 = 1、0.896 = 0 等...

如何正常读取浮点数?在这种情况下,至少有 2 个精度点(尽管使用真实 .csv 文件的值可以达到 6 个精度点)

要注意的另一件事是,这会打印出 3 次“缺少运算符”。我认为这可能是由于间距,但不确定在哪里。

脚本如下:

@echo off

set cur=0
set max=0

for /f "usebackq tokens=1-4 delims=," %%a in ("sample.csv") do (call :func "%%d")
echo Max is %max%
goto :here

:func
 set /a cur=%1
 if %cur% gtr %max% (set /a max=%cur%)
 goto :eof

:here

pause

这是 sample.csv,可以正常工作:

1,2,,3,3,5,,
5,6,,7,12.3,6,,
9,10,,11,11.4,7,,
13,14,,15,10.1,2,,

我添加了一些额外的逗号,只是为了测试代码。

【问题讨论】:

嗯,不,默认情况下,您不能使用批处理文件进行分数。我强烈推荐powershell,话虽如此,你不能仅仅为了测试而添加逗号。一个csv文件是有格式的,通常内容应该和header匹配,如果你随意添加,那是没有意义的。 Gerhard,我会研究一下 powershell,谢谢。话虽如此,我的另一个程序生成的真实 .csv 具有空列的点,这些点显示为“,”。我只是想看看 for 循环是否会跳过它或抛出一些错误。此外,它似乎没有将其算作一列,因为在上面的示例中,到第 4 列仍然到达 3、12.3、11.4 和 10.1 是的,这是可以理解的,因为并非所有字段都有值,但您的列将是相等的。 【参考方案1】:

如果您要进行实际计算,那么在使用分数时我不建议使用batch-file,而是为了简单地测试最高值,我们可以通过. 匹配任一侧来分割字符串。不过,您仍然不能使用 set /a 使其成为实际整数:

@echo off & setlocal enabledelayedexpansion
set num=0 & set frac=0 
for /f "usebackq tokens=1-4 delims=," %%a in ("sample.csv") do (
  for /f "tokens=1* delims=." %%i in ("%%~d") do (
      if not "%%j" == "" if %%i gtr !num! (
         set "num=%%i"
         set "max=%%~d"
  )
      if %%i geq !num! if %%~j gtr !frac! (
         set "frac=%%~j"
         set "max=%%~d"
    )
  )
)
echo Max is %max%
pause

根据您对~ 的评论,这里是for /? 的摘录

In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:

    %~I         - expands %I removing any surrounding quotes (")
    %~fI        - expands %I to a fully qualified path name
    %~dI        - expands %I to a drive letter only
    %~pI        - expands %I to a path only
    %~nI        - expands %I to a file name only
    %~xI        - expands %I to a file extension only
    %~sI        - expanded path contains short names only
    %~aI        - expands %I to file attributes of file
    %~tI        - expands %I to date/time of file
    %~zI        - expands %I to size of file
    %~$PATH:I   - searches the directories listed in the PATH
                   environment variable and expands %I to the
                   fully qualified name of the first one found.
                   If the environment variable name is not
                   defined or the file is not found by the
                   search, then this modifier expands to the
                   empty string

The modifiers can be combined to get compound results:

    %~dpI       - expands %I to a drive letter and path only
    %~nxI       - expands %I to a file name and extension only
    %~fsI       - expands %I to a full path name with short names only
    %~dp$PATH:I - searches the directories listed in the PATH
                   environment variable for %I and expands to the
                   drive letter and path of the first one found.
    %~ftzaI     - expands %I to a DIR like output line

In the above examples %I and PATH can be replaced by other valid
values.  The %~ syntax is terminated by a valid FOR variable name.
Picking upper case variable names like %I makes it more readable and
avoids confusion with the modifiers, which are not case sensitive.

【讨论】:

这实际上工作得很好。谢谢!但是 tilda 是什么意思呢?喜欢在 ("%%~d") 中? 用于定义变量如何展开。所以在这种情况下,它只是删除了周围的双引号。虽然这里很可能不需要它,但数字用双引号括起来可能会有变化。即9,10,,11,"11.4",7,,。您可以通过运行 for /? 查看扩展变量的所有选项,但我冒昧地将特定部分复制到我的答案中。【参考方案2】:

正如 cmets 中提到的,您可以使用 powershell 来完成此任务。这是一个基本的想法。

示例文件内容:

1,2,,3,3,5,,
5,6,,7,12.3,6,,
9,10,,11,11.4,7,,
13,14,,15,10.1,2,,

你可以使用类似的东西:

Import-Csv -Path ".\sample.csv" -Header ("A","B","C","D","E") | Sort-Object  [Single]$_.E  -Descending | Select-Object -First 1 -ExpandProperty E

应该返回:

12.3

正如你在上面看到的,因为你没有提供标题记录,我不得不创建一些来识别我的目标字段。但是,如果您已经知道标头字段,则可以稍微简化代码。

示例文件内容:

This,Is,My,Actual,Header,Record,,
1,2,,3,3,5,,
5,6,,7,12.3,6,,
9,10,,11,11.4,7,,
13,14,,15,10.1,2,,

您只需根据其标题值名称命名您的字段,例如:

Import-Csv -Path ".\sample.csv" | Sort-Object  [Single]$_.Header  -Descending | Select-Object -First 1 -ExpandProperty Header

应该再次返回:

12.3

【讨论】:

是的,powershell 显然是这里更好的解决方案!与我的回答相比,whixh 确实有效,ps 代码要少得多,而不是 hack。 我建议@Gerhard,无论如何都会选择您的答案。我的回答不符合问题参数,因为没有提到 PowerShell,没有 [powershell] 标签,而且我没有以可以直接从 batch-file 运行的方式提供代码。

以上是关于批处理文件:从 .csv 文件中读取浮点值的主要内容,如果未能解决你的问题,请参考以下文章

Jmeter读取CSV参数化文件

如何从数据库中读取值,例如 jmeter 中的 csv 文件

如何从流中读取 CSV 文件并在写入时处理每一行?

读取csv字典变成str了怎么办

Spring Batch中如何读取多个CSV文件合并数据进行处理?

如何读取内存中的 csv 文件以进行快速处理?