2013-02-22 89 views
1

我只需要一個方便的小工具來檢查文本文件中的重複行,它會刪除這些重複項。因此,如果該文件說:如何批量檢查大文本文件中的重複項?

A 
B 
C 
D 
A 
E 

就會變成:

A 
B 
C 
D 
E 

尼斯和簡單。但是文本文件會很大,並且存在很長的文件位置,我需要確保沒有任何一個文件。只要只有一個保留,刪除哪個副本並不重要。所以,我會好起來的東西,如:

B 
C 
D 
A 
E 

這裏的一切,我到目前爲止有:

@echo off 
SetLocal EnableDelayedExpansion 
set v=0 
FOR /F "usebackq delims=" %%a in ("SomeArray.txt") do (
set /a var+=1 
set var!v!=%%a 
) 
pause 

我不知道從哪裏開始就使循環測試所有可能的重複。從命令行

@echo off 
set prev= 
for /f %%a in ('sort %1') do call :oneline %%a 
goto :eof 

:oneline 
if NOT !%1!==!%prev%! echo %1 
set prev=%1 
goto :eof 

電話:

+0

我有代碼讀取文件,並將所有行設置爲標題爲var1,var2,var3 ect的變量。 – BBMAN225 2013-02-22 21:38:15

回答

1

創建一個cmd文件uniqeline.cmd與此內容

uniqeline yourfilewithfilesnames.lst 
1

你的代碼行存儲在一個 「陣列」 被打破了。您應該遞增v而不是var

檢查重複項的代碼很簡單,但速度很慢。簡單地遍歷現有的值來查看它是否與當前行匹配。只有在找不到匹配的情況下回顯並存儲當前行。獨特線條的數量越多,它越慢。

下面的腳本預計該文件作爲1號和唯一的參數名稱

@echo off 
setlocal enableDelayedExpansion 
set n=0 
for /f "usebackq delims=" %%A in (%1) do (
    set "skip=" 
    for /l %%N in (1 1 !n!) do if "%%A"=="!var%%N!" set skip=1 
    if not defined skip (
    echo %%A 
    set /a n+=1 
    set "var!n!=%%A" 
) 
) 

以上,如果符合;開始,因爲FOR/F EOL選項默認會跳過打頭的行會失敗;。這可以固定一些尷尬的語法,同時設置EOL和DELIMS到什麼:因爲延遲擴張將破壞FOR/F的變量被擴展時,該行的值usebackq^ delims^=^ eol^=

以上還將如有線包含!失敗。這可以通過根據需要仔細啓用和禁用延遲擴展來解決。

@echo off 
setlocal disableDelayedExpansion 
set n=0 
for /f usebackq^ delims^=^ eol^= %%A in (%1) do (
    set "ln=%%A" 
    set "skip=" 
    setlocal enableDelayedExpansion 
    for /l %%N in (1 1 !n!) do if "!ln!"=="!var%%N!" set skip=1 
    if defined skip (endlocal) else (
    echo !ln! 
    set /a n+=1 
    for %%N in (!n!) do (
     endlocal 
     set "var%%N=%%A" 
     set "n=%%N" 
    ) 
) 
) 

但有更快更簡單的解決方案。

最快且最簡單的純批處理解決方案是將行內容合併到變量的名稱中。要檢查重複項,只需檢查變量是否已經定義。

@echo off 
setlocal 

:: clear existing _ variables 
for /f "eol== delims==" %%V in ('set _ 2^>nul') do set "%%V=" 

:: read and echo file, throw away duplicates (case insensitive) 
:: does not work if line contains = 
for /f usebackq^ delims^=^ eol^= %%A in (%1) do (
    if not defined _%%A (
    echo %%A 
    set "_%%A=1" 
) 
) 

上述解決方案有兩個主要侷限性。

  • 重複比較不區分大小寫,因爲變量名不區分大小寫。

  • 該解決方案將無法正確檢測包含=的重複項,因爲=不能包含在變量名中。


我相信劉若英的解決方案使用排序是最好的普遍適用的方法,但劉若英的代碼有以下缺點

  • 使用CALL的顯著降低性能(明顯有大文件)

  • ;開頭的行被跳過

  • 特殊字符,如&|<>^導致問題

  • 腳本假設只存在分隔標記一個空間

的缺點是容易解決:

@echo off 
setlocal disableDelayedExpansion 
set "old=" 
for /f delims^=^ eol^= %%A in ('sort %1') do (
    set "new=%%A" 
    setlocal enableDelayedExpansion 
    if "!new!" equ "!old!" (endlocal) else (
    echo !new! 
    endlocal 
    set "old=%%A" 
) 
) 

所有批次的解決方案是有限的最大行長度爲〜8191個字符。

此外,上述所有解決方案都會清空空行。