【问题标题】:How can I read a comma delimited text file in a Windows batch file?如何在 Windows 批处理文件中读取逗号分隔的文本文件?
【发布时间】:2015-02-09 18:18:39
【问题描述】:

我有下一个文件 txt,只有一行:

1,2,3,4,5, 6,..., n

我需要捕获所有用逗号分隔的数字。

【问题讨论】:

  • 这可能会回答你的问题:stackoverflow.com/questions/134001/…
  • 是的,但它是固定文件
  • 在我的情况下,“数字”的数量可能会有所不同
  • 您需要更具体地了解“捕获”的含义。你到底想对这些数字做什么?将它们存储在数组中?打印它们,每行一个? ...
  • 是的,打印出来,每行一个。

标签: batch-file


【解决方案1】:
@echo off
setlocal

set /P "numbers="<csvfile

for %%I in (%numbers%) do (
    echo %%I
)

不带开关的for 命令使用逗号、分号、空格和制表符作为分隔符。在上面的示例中,%%I 将从左到右依次为每个数字。

【讨论】:

  • +1 只要行长不超过 1021 字节,它就可以工作。您可以改为使用 FOR /F 读取该行,但随后行长度限制增加到略小于 8191 字节。
  • 澄清一下,dbenham 正在谈论 set /P "numbers="&lt;csvfile 行被限制为 1021 个字节。替代方案是for /f "usebackq delims=" %%I in ("csvfile") do set "numbers=%%~I"。仍然需要第二个for 循环将%numbers% 变量拆分为未知数量的实体。
  • @dbenham - 你找到了关于+1 的解决方法:-)
  • @npocmaka - 是的,我在某处的评论中看到了这一点,我认为是在元数据中。我们将不得不等待,看看它需要多长时间才能被禁止。
  • @dbenham +一种贴在男人身上的方法。 (我也试过 +1 但 cmets 显然不允许 HTML 实体。)
【解决方案2】:
@echo off
    setlocal enableextensions enabledelayedexpansion

    rem Variable to hold digits while reading numbers
    set "number="
    rem Variable to hold the table index where data is captured
    set "n=0"

    rem Decompose input file in characters and filter
    for /f %%a in ('
        cmd /q /u /c "type numbers.txt&echo(," ^| more ^| findstr /r /x /c:"[0-9,]"
    ') do if "%%a"=="," (
        rem If a comma is found, capture current number
        if defined number set /a "numbers[!n!]=!number!", "n+=1"
        set "number="
    ) else (
        rem If it is not a comma, is a number to concatenate to current one
        set "number=!number!%%a"
    )

    rem Show numbers captured
    set numbers[

这会将每个值“捕获”到数组的元素中。由于完整数据必须通过for 命令加载到内存中,并且输入文件中的每个有效字符都将包含一个 CRLF 结尾,因此输入行的限制约为 715 MB。

【讨论】:

  • +1 我经常忘记那个 unicode 技巧。这很好用,但在处理大型数据集时会很慢。
【解决方案3】:

rojo 为相对较小的数据集提供了一个很好的解决方案。

MC ND 为大型数据集展示了一个很好的纯批处理解决方案,但它可能会变得很慢。

大型数据集的快速解决方案需要使用纯批处理以外的其他方法。一种选择是我的JREPL.BAT utility,这是一种混合 JScript/批处理脚本,可以对文本执行正则表达式替换。

假设 JREPL.BAT 在您的 PATH 中的某个位置,并且您的 csv 是“test.csv”,那么以下将打印出每个数字,每行一个:

jrepl "," "\n" /x /f "test.csv"

由于 JREPL 是一个批处理脚本,如果您想在另一个批处理脚本中使用它,则必须使用 CALL JREPL

下面显示了如何将数字存储在变量“数组”中,使用 FINDSTR 建立数组索引。请注意,我不需要call jrepl,因为在 FOR IN('') 子句中使用了 jrepl:

@echo off
setlocal enableDelayedExpansion

:: Store the numbers in an array
for /f "tokens=1,2 delims=:" %%A in (
  'jrepl "," "\n" /x /f "test.csv" ^| findstr /n "^"'
) do (
  set "n[%%A]=%%B"
  set "n.count=%%A"
)

:: Display the numbers
for /l %%N in (1 1 %n.count%) do echo !n[%%N]!

或者您可以使用 JREPL 解析数字并建立索引值。这需要更多的代码,但效率更高:

@echo off
setlocal enableDelayedExpansion

:: Store the numbers in an array
for /f "tokens=1,2 delims=:" %%A in (
  'jrepl "\d+" "(n+=1)+':'+$0" /jmatch /jbeg "var n=0" /f "test.csv"'
) do (
  set "n[%%A]=%%B"
  set "n.count=%%A"
)

:: Display the numbers
for /l %%N in (1 1 %n.count%) do echo !n[%%N]!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    相关资源
    最近更新 更多