【问题标题】:How to read text file line by line which is excessing characters in batch file? Limiting the line length is allowed.(Windows, batch script)如何逐行读取批处理文件中多余字符的文本文件?允许限制行长。(Windows,批处理脚本)
【发布时间】:2020-06-15 20:42:14
【问题描述】:
##test.txt##
First line = 1;*|:12345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345
Second line = 5;*|:3215432;*|:21543215432154321543215432154321543215432154321543215432154321543215;*|:543215;*|:5432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321543215432154321

SetLocal EnableDelayedexpansion
for /F "tokens=* delims=" %%a in ('type "test.txt"') do (
            set "Line=%%a"
            echo Line: "!Line!"
)

显然,上面的代码无法读取 test.txt 中的 2 行,因为每行都超过了限制(8191 个字符)。

通过输入

type "test.txt"

它仍然产生了 test.txt 文件中的 2 行。但是,一旦有 2 行进入 for 循环,就无法读取这些行。

我不需要整行,所以我尝试通过删除多余的部分字符串来预处理文本文件。例如,将上例中的行长度限制为 8100。

1.如何在windows环境下不使用记事本(任何GUI编辑器)编辑上述文本文件?

2.如果我不需要对文件进行预处理,有什么技巧可以避免上述问题?

  • 即使我不能放胡萝卜(^),它会扩展命令行。我想要的是拆分字符串并获取第一部分很好,但我不想通过记事本或其他 GUI 文件编辑器手动完成。

【问题讨论】:

  • 取决于文件内容。它只包含数字/字母还是冒号/空格?
  • @jeb 它还包含冒号和其他特殊字符,例如 (,)、% 等。
  • 第一列的大小有限制吗?你需要多少?可以用|作为分隔符吗?
  • @jeb 感谢您的关注。不,我不能使用 |作为分隔符,因为该行将由第一个“=”等号分隔。如果您的意思是,第一行和第二行部分作为第一列.. 它不是固定的和有限的。

标签: string windows batch-file cmd


【解决方案1】:

如果您使用的是受支持的 Windows 系统,则可以使用 PowerShell。将20 更改为每行所需的最大字符数。

powershell -NoLogo -NoProfile -Command ^
    "Get-Content -Path '.\longlines.txt' |" ^
        "ForEach-Object { $_.substring(0,[Math]::min($_.Length, 20)) }"

【讨论】:

    【解决方案2】:

    您可以使用块读取器,它将每一行分成最大大小为 1023 个字符的块。

    @echo off
    setlocal EnableDelayedExpansion
    
    set pos=0
    set line=
    <long_text.txt (
        FOR /F "tokens=1 delims=:" %%1 in ('findstr /o "^" long_text.txt') DO (
            set new_pos=%%1
            set /a size=new_pos-pos
            set /a "chunks=(size-1+1022) / 1023"
            if defined line echo Line: !line! chunks=!chunks!
    
            set /a pos=new_pos
            for /L %%# in (1 1 !chunks!) do (
                set "partial="
                set /p partial=     
                if defined partial (
                    echo   #!line! chunk %%# -- !partial:~0,10! ... !partial:~-10! 
                )
            )
            set /a line+=1
        )
    )
    

    工作原理

    外部FOR /F .. findstr /O循环用于通过计算两条线之间的位置差来确定每条线的长度。
    行长用于计算必须读取多少 才能获取整行。

    一行本身由set /p 读取(它从&lt;long_text.txt 的重定向中读取)。 set /p 的内置限制为 1023 个字符。

    因此,set /p 被使用 chunk 次。

    要计算单行使用了多少块,行长必须除以 1023,但必须减去 1 个字符,因为 LF 不算数(但 CR)。 +1022 是这样一个事实的结果,即最后一个 complete 块之后的剩余字符也必须被读取。
    如果该行是 1023 的倍数(也是空行),则最后一个块可以为空。

    唯一剩下的点是最后一行。
    这种技术不会读取最后一行,但在前面附加一个空行很容易。

    【讨论】:

    • 代码有效,我会根据这个块阅读器工作。非常感谢! @jeb
    • 我不确定为什么现在设置代码 new_pos=%%1。使用 %%2,它可以工作,但不能使用 %%1。我认为有一个错误的更新。
    • @JoeyCho,我想你没有复制完整的更新代码。首先我使用%%2 和两个令牌和findstr /N /O,但我删除了多余的部分
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    相关资源
    最近更新 更多