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!
的内容!读取数组代码>is2008-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
在第一节末尾,当的内容!读取数组代码>is2008-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建议对您的帖子进行编辑,以修复导致语法错误的打字错误。