代码之家  ›  专栏  ›  技术社区  ›  call me Steve

批处理文件以保留十行中的一行

  •  2
  • call me Steve  · 技术社区  · 17 年前

    我有一个n行的文件。(n超过1亿)

    我想输出一个只有10行中的1行的文件,我不能将文件分成10部分,而只保留一部分,因为它必须是随机的。后来我不得不做一个统计分析,我不能在数据中制造一个强烈的偏差)。

    我正在考虑读取文件,如果每个记录的编号为mod 10,则输出它。

    • 这是一台windows(可能是加固版)计算机,可能是XP Vista或windows server 2003。

    • 没有可用的开发工具

    因此,我想到了windows批处理文件(我不能假设powershell和vbscript可能已被删除)。现在来看FOR/F命令。

    谢谢保罗的回答。 我(在Hosam帮助下)重新格式化答案,将其放入批处理文件:

    @echo off
    setlocal   
    findstr/N . inputFile| findstr ^[0-9]*0: >temporaryFile
    FOR /F "tokens=1,* delims=: " %%i in (temporaryfile) do echo %%j > outputFile
    

    感谢quux和Pax提供类似的替代解决方案。然而,在对更大的文件进行快速测试后,Paul的答案大约快了8倍。我猜评估(在集合中)有点慢,即使逻辑看起来很好。

    4 回复  |  直到 17 年前
        1
  •  6
  •   The Archetypal Paul    17 年前

    好吧,我想我已经破解了:

    findstr/N . path-to-log-file | findstr ^[0-9]*0:
    

    (使用findstr将行号添加到行首,然后再次仅打印行号以零结尾的行)

    使用删除行号和冒号

    FOR /F "tokens=1,2* delims=: " %i in (file-with-linenumbers) do echo %j
    

    保罗。

        2
  •  2
  •   paxdiablo    17 年前

    这里有一个小的命令脚本,它可以满足您的需要(精确地每隔10行打印文件lines32.txt)。该文件(用于我的测试)包含数字1到32,每行一个,输出为10、20、30。

    @echo off
    setlocal
    
    set /a "n = 0"
    for /f %%i in (lines32.txt) do call :fn %%i
    endlocal
    goto :eof
    
    :fn
    set /a "n = n + 1"
    if not %n%==10 goto :eof
    echo %1
    set /a "n = 0"
    goto :eof
    

        3
  •  1
  •   Hosam Aly    17 年前

    保罗有一个很好的答案。通过添加重定向操作符,可以将数据写入文件。

    findstr /n . yourLogFile.txt | findstr ^[0-9]*0: > numberedFile.txt
    for /f "tokens=1,2* delims=:" %i in (numberedFile.txt) do echo %j > smallFile.txt
    del numberedFile.txt
    

    如果从命令行运行,这将起作用。如果要将其放入批处理文件中,请将每个“%”字符替换为“%”(这样%i将变成%%i,%j将变成%%j,因为在批处理文件中“%”具有特殊含义)。

        4
  •  1
  •   quux    17 年前

    选择的答案可能需要很长时间才能处理,因为它必须处理整个文件两次。如果该文件有数百万行。。。哇。

    这是我想到的。它将简单地按顺序处理文件,打印每10行(以您喜欢的数字结尾):

    @ECHO OFF
    SETLOCAL
    SET lastdigit=7
    SET linecounter=0
    FOR /F "tokens=*" %%a IN (text.txt) DO CALL :picker %%a
    ENDLOCAL
    GOTO :eof
    
    :picker
    set line=%*
    IF {%linecounter:~-1%} == {%lastdigit%} ECHO %linecounter% %line%
    SET /a linecounter=%linecounter% + 1
    GOTO :eof
    

    每行都从零开始编号。%linenumber%以%lastdigit%结尾的任何行都将与行号一起回显到控制台。使用set/?看看我是怎么想到的