你的代碼行存儲在一個 「陣列」 被打破了。您應該遞增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個字符。
此外,上述所有解決方案都會清空空行。
我有代碼讀取文件,並將所有行設置爲標題爲var1,var2,var3 ect的變量。 – BBMAN225 2013-02-22 21:38:15