将文件读入数组并将块写出

  • 本文关键字:数组 文件 batch-file cmd
  • 更新时间 :
  • 英文 :


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

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

我想将这些行读入数组,对它们进行排序并将包含 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 语句不起作用。

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

编辑修复了小错误

@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/

我通常不会像这样格式化我的代码,但@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那里窃取了代码。这里和这里

WindowsSORT命令不按数字排序。 所以你需要做一些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/

这相对简单。此代码获取文件内容,对其进行排序,然后以五 (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',')}

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

@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

最新更新