批量过滤重复行并写入新文件(半成品)

时间:2011-11-15 15:23:58

标签: 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 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!

!read-array!的内容为2008-12-12;2007-01-01;2009-06-06

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

2008-12-12
2007-01-01
2009-06-06

所以这就是我到目前为止所提出的。

我遇到的问题是第二个for - 循环在嵌套时不接受!loop!变量作为标记定义。但是,如果它没有嵌套,它会接受%loop%。 我这样做的原因是!read-array!可能有未知数量的项目,因此我也算数。 有任何想法吗?

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

1 个答案:

答案 0 :(得分:2)

在第一部分结束时,当!read-array!的内容为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%
)