Batch file 批处理筛选重复行并写入新文件(半成品)

Batch file 批处理筛选重复行并写入新文件(半成品),batch-file,for-loop,duplicates,nested-loops,no-duplicates,Batch File,For Loop,Duplicates,Nested Loops,No Duplicates,我已经成功地制作了一个脚本,它可以过滤掉文件中的重复行,并将结果保存到一个分隔的变量分号(类似于“数组”)中。我找不到任何真正好的解决办法 @echo off setlocal enabledelayedexpansion rem test.txt contains: rem 2007-01-01 rem 2007-01-01 rem 2007-01-01 rem 2008-12-12 rem 2007-01-01 rem 2009-06-06 rem ... and so on set f

我已经成功地制作了一个脚本,它可以过滤掉文件中的重复行,并将结果保存到一个分隔的变量分号(类似于“数组”)中。我找不到任何真正好的解决办法

@echo off
setlocal enabledelayedexpansion

rem test.txt contains:
rem 2007-01-01
rem 2007-01-01
rem 2007-01-01
rem 2008-12-12
rem 2007-01-01
rem 2009-06-06
rem ... and so on

set file=test.txt

for /f "Tokens=* Delims=" %%i in ('type %file%') do (
    set read=%%i
    set read-array=!read-array!;!read!
)

rem removes first trailing ";"
set read-array=!read-array:*;=!
echo !read-array!

for /f "Tokens=* Delims=" %%i in ('type %file%') do (
    set dupe=0
    rem searches array for the current read line (%%i) and if it does exist, it deletes ALL occurences of it
    echo !read-array! | find /i "%%i" >nul && set dupe=1
    if ["!dupe!"] EQU ["1"] (
        set read-array=!read-array:%%i;=!
        set read-array=!read-array:;%%i=!
    )
    rem searches array for the current read line (%%i) and if it does not exist, it adds it once
    echo !read-array! | find /i "%%i" >nul || set read-array=!read-array!;%%i
)

rem results: no duplicates
echo !read-array!
的内容!读取数组is
2008-12-12;2007-01-01;2009-06-06

现在,我想取出数组中的每个项目,并将它们写入一个新文件,每个项目后面都有换行符。例如:

2008-12-12
2007-01-01
2009-06-06
这就是我到目前为止的想法

我遇到的问题是的第二个
循环不接受
!循环变量作为嵌套时的标记定义。但是,如果它不是嵌套的,它确实接受
%loop%
。 我这样做的原因是
!读取数组可能有未知数量的项目,因此我也会计算它们。
有什么想法吗

rem count items in array
set c=0
for %%i in (!read-array!) do set /a c+=1

echo %c% items in array
for /l %%j in (1,1,%c%) do (
    set loop=%%j
    for /f "Tokens=!loop! Delims=;" %%i in ("!read-array!") do (
        echo %%i
        rem echo %%i>>%file%
    )
)
exit /b

在第一节末尾,当
的内容!读取数组is
2008-12-12;2007-01-01;2009-06-06
,您可以使用简单的
for
直接分隔“列表”中的元素,因为批处理文件中的标准分隔符除空格外,还可以是逗号、分号或等号:

for %%i in (%read-array%) do echo %%i
不过,我可以向您推荐一种更简单的方法吗

为什么不用行的下标值定义一个“实”数组呢?这样,几个重复的行将其值存储在同一数组元素中。最后,只显示结果元素的值:

@echo off
set file=test.txt
for /F "Delims=" %%i in (%file%) do (
    set read-array[%%i]=%%i
)
rem del %file%
for /F "Tokens=2 Delims==" %%i in ('set read-array[') do (
    echo %%i
    rem echo %%i>>%file%
)
编辑 替代解决方案

还有另一种方法,可以按照您的建议,组合一个以分号分隔的值列表。在这种情况下,每个值首先从以前的列表内容中删除,然后立即再次插入,所以在循环结束时,每个值只出现一次

@echo off
setlocal EnableDelayedExpansion
set file=test.txt
for /F "Delims=" %%i in (%file%) do (
    set read-array=!read-array:;%%i=!;%%i
)
rem del %file%
for %%i in (%read-array%) do (
    echo %%i
    rem echo %%i>> %file%
)

第一节结束了吗?你是指这两行吗<代码>for/f“Tokens=*Delims=“%%i in('type%file%')do(
我也会尝试你关于使用真实数组的建议,我以前不知道也没有使用过它们。无论如何,我还是想知道为什么我不能像我的例子那样为
-循环嵌套第二个
。@Niklas:在
!read array!
的内容之后!是
2008-12-12;2007-01-01;2009-06
,将每个项目分开,只需一个se
对于%%i in(%read array%)执行回显%%i
。对于嵌套的第二个
执行回显(
),您可以删除循环变量,并按以下方式写入:
对于/f“Tokens=%%j Delims=;”%%i in(!read array!)执行回显操作(
。我还包括了另一个批处理文件,该批处理文件使用了原始的分号分隔值列表方法。我得到的
命令语法不正确。
对于此行
for/F“Tokens=2 Delims==”%%I in('set read array['))我不知道为什么。你的第二个建议看起来很有希望,我会试试。但是你建议的嵌套
for
-循环使用
%%j
作为标记,这不是应该是
%%I
,这真的会从分号分隔的变量逐行返回值吗?你的两个解决方案都很好。我已经知道了owever建议对您的帖子进行编辑,以修复导致语法错误的打字错误。