将文件读入数组并写出块

时间:2018-10-18 16:31:03

标签: batch-file cmd

我有一个包含以下内容的文件:

1005
1010
1011
1012
1013
1014
1009
1015
1006
77
1016
1017
1018
1019
1020
1021
1022
1023
1008

我想将这些行读入数组,对其进行排序,然后将包含5个元素的块写到一个新文件中

输出文件应如下所示(每行5个元素)。

xyz 77,1005,1006,1008,1009
xyz 1010,1011,1012,1013,1014
...

我当前的批处理脚本如下:

@echo off &setlocal disabledelayedexpansion

Sort Knot_unsort.dat>Knot_sort.dat

set /A i=0

for /F "delims=" %%a in (Knot_sort.dat) do (
    set /A i+=1
    call set array[%%i%%]=%%a
)
call set n=%%i%%

for /L %%i in (1,1,%n%) do (
    set /a b = %%i %% 5

    if %b% == 0 (
        :: does not work
    )

    call echo %%b%%
)

对内容进行排序并将行读入数组。但是在那之后,我不知道如何将五个元素合并为一个新变量并将它们写回到一个新文件中。 我尝试使用模,但是if语句不起作用。

4 个答案:

答案 0 :(得分:2)

这是相对简单的。此代码获取文件内容,对其进行排序,然后以五(5)为一组的形式输出。

powershell -NoProfile -Command ^
    "$items = Get-Content -Path '.\Knot_unsort.txt' | Sort-Object { [int]$_ };" ^
    "for ($i=0; $i -lt $items.Length; $i+=5) { 'xyz ' + $($items[$i..($i+4)] -join ',') }"

示例输出:

xyz 77 1005 1006 1007 1008
xyz 1009 1010 1012 1013 1014
xyz 1015 1016 1017 1018 1019
xyz 1020 1021 1022 1023

我不是一名标准高尔夫球手,但是如果您需要单线的话:

powershell -nop "$items=gc .\Knot_unsort.txt|sort{[int]$_};for($i=0;$i-lt$items.Length;$i+=5){'xyz '+$($items[$i..($i+4)]-join',')}

答案 1 :(得分:2)

我通常不这样格式化我的代码,但@lit使我满意。

@echo off & setlocal enabledelayedexpansion
((FOR /F "TOKENS=1* DELIMS=:" %%G IN ('sort Knot_unsort.dat^|findstr /N "^"') DO (set /A "mod=%%G %% 5" &IF !mod! == 0 (echo xyz!line! %%H& set "line=") ELSE (SET "LINE=!LINE! %%H"))) &IF DEFINED LINE echo xyz!line!)>foo.dat

在现实世界中,我会像这样格式化它。

@echo off & setlocal enabledelayedexpansion
((FOR /F "TOKENS=1* DELIMS=:" %%G IN ('sort Knot_unsort.dat^|findstr /N "^"') DO (
    set /A "mod=%%G %% 5" 
    IF !mod! == 0 (echo xyz!line! %%H& set "line=") ELSE (SET "LINE=!LINE! %%H")
)) &IF DEFINED LINE echo xyz!line!)>foo.dat

如果您真的想做自己的阵列伏都教,则可以简化为它。

@echo off & setlocal enabledelayedexpansion

for /F "tokens=1* delims=:" %%G in ('sort Knot_unsort.dat^|findstr /N "^"') do (
    set "array[%%G]=%%H"&set "n=%%G"
)

((for /L %%I in (1,1,%n%) do (
    set /a "mod= %%I %% 5"
    IF !mod! == 0 (echo xyz!line! !array[%%I]!&set "line=") ELSE (SET "LINE=!LINE! !array[%%I]!")
))&IF DEFINED LINE echo xyz!line!)>foo.dat

更新: 好吧,他们说模仿是最恭维的奉承方式。我已经两次从@Aacini窃取了此更新代码的代码。 HereHere

Windows SORT命令未按数字排序。因此,您需要执行一些Tom Foolery才能做到这一点。这是我更新的代码。

@echo off
setlocal EnableDelayedExpansion

for /F "delims=" %%j in (Knot_unsort.dat) do (
   set j=0000000%%j
   set name[!j:~-8!]=%%j
)

set "i=0"
<nul (for /F "tokens=2 delims==" %%a in ('set name[') do (
   set /A "i=(i+1)%%5"
   if !i! equ 1 (set /P "=xyz %%a") else set /P "=,%%a"
   if !i! equ 0 echo/
))
if %i% neq 0 echo/

答案 2 :(得分:2)

另一种更简单的方法,不将行存储在变量中...

编辑已修复小错误

@echo off
setlocal EnableDelayedExpansion

set "i=0"
<nul (for /F %%a in ('sort Knot_unsort.dat') do (
   set /A "i=(i+1)%%5"
   if !i! equ 1 (set /P "=xyz %%a") else set /P "=,%%a"
   if !i! equ 0 echo/
))
if %i% neq 0 echo/

输出:

xyz 1005,1006,1007,1008,1009
xyz 1010,1011,1012,1013,1014
xyz 1015,1016,1017,1018,1019
xyz 1020,1021,1022,1023

编辑管理数字位数可变(最多8位)的数字的新方法

@echo off
setlocal EnableDelayedExpansion

set "i=0"
<NUL (
   for /F "tokens=2 delims=/ " %%a in (
      '(for /F %%i in (Knot_unsort.dat^) do @(set /A 100000000+%%i ^& echo /%%i^)^) ^| sort'
                                      ) do (
      set /A "i=(i+1)%%5"
      if !i! equ 1 (set /P "=xyz %%a") else set /P "=,%%a"
      if !i! equ 0 echo/
   )
)
if %i% neq 0 echo/

答案 3 :(得分:1)

我现在想出了这段代码。也许有人可以使用它。 如果您有更好更好的方法,请随时发表评论。

@echo off & setlocal enabledelayedexpansion

Sort Knot_unsort.dat>Knot_sort.dat

set /A i=0

for /F "delims=" %%a in (Knot_sort.dat) do (
    set /A i+=1
    call set array[%%i%%]=%%a
)
call set n=%%i%%

set var=
set newlist=
set /A j=0
for /L %%i in (1,1,%n%) do (
    set /a b = %%i %% 5

    if !b!==0 (
        set /A j+=1
        ::call echo %%b%%
        call set var=%%var%%%%array[%%i]%%,
        call set newlist[%%j%%]=%%var%%
        call set var=
    ) else (
        call set var=%%var%%%%array[%%i]%%,
    )

)
::call echo %j%

call set n=%%j%%

for /L %%i in (1,1,%n%) do (
    call echo XYZ - %%newlist[%%i]:~0,-1%%
) >> foo.dat