我有一个包含以下内容的文件:
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语句不起作用。
答案 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窃取了此更新代码的代码。 Here和Here
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