是否可以從文本文件中刪除重複的行?如果是,如何?批處理從文本文件中刪除重複的行
回答
當然可以,但是像大多數批量處理文本文件一樣,它並不漂亮,而且速度也不是特別快。
此解決方案在查找重複項時忽略大小寫,並對行進行排序。該文件的名稱作爲批處理腳本的第一個參數和唯一參數傳入。
@echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "sorted=%file%.sorted"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^
::The 2 blank lines above are critical, do not remove
sort "%file%" >"%sorted%"
>"%deduped%" (
set "prev="
for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%sorted%") do (
set "ln=%%A"
setlocal enableDelayedExpansion
if /i "!ln!" neq "!prev!" (
endlocal
(echo %%A)
set "prev=%%A"
) else endlocal
)
)
>nul move /y "%deduped%" "%file%"
del "%sorted%"
該解決方案是大小寫敏感的,它留下的原始順序的線(除了當然一式兩份)。文件的名字再次作爲第一個也是唯一的參數傳入。
@echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "line=%file%.line"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^
::The 2 blank lines above are critical, do not remove
>"%deduped%" (
for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file%") do (
set "ln=%%A"
setlocal enableDelayedExpansion
>"%line%" (echo !ln:\=\\!)
>nul findstr /xlg:"%line%" "%deduped%" || (echo !ln!)
endlocal
)
)
>nul move /y "%deduped%" "%file%"
2>nul del "%line%"
EDIT
上述條空行這兩個解決方案。在談論不同的價值時,我並不認爲空白的線條值得保留。
我修改了兩種解決方案來禁用FOR/F「EOL」選項,以便保留所有非空行,而不管第一個字符是什麼。修改後的代碼將EOL選項設置爲換行字符。
新的解決方案2016年4月13日:JSORT.BAT
你可以用我JSORT.BAT hybrid JScript/batch utility高效排序和刪除重複的線路用一個簡單的襯墊(加上一個MOVE覆蓋原文件最終結果)。 JSORT是純粹的腳本,可以在XP以後的任何Windows機器上本機運行。
@jsort file.txt /u >file.txt.new
@move /y file.txt.new file.txt >nul
set "file=%CD%\%1"
sort "%file%">"%file%.sorted"
del /q "%file%"
FOR /F "tokens=*" %%A IN (%file%.sorted) DO (
SETLOCAL EnableDelayedExpansion
if not [%%A]==[!LN!] (
set "ln=%%A"
echo %%A>>"%file%"
)
)
ENDLOCAL
del /q "%file%.sorted"
這應該工作完全相同。 dbenham的例子對我來說似乎太硬了,所以,測試了我自己的解決方案。使用例如:filedup.cmd文件名.ext
僅供參考:第一個'set'語句不會總是有效。我看到%CD%失敗和/或被覆蓋很多次!你應該使用這個,而不是'set「file =%〜dpnx1」'。 %1中的字母定義爲:d =驅動器,p =路徑,n =文件名(不帶擴展名),x =擴展名。這適用於第一個參數,即使您只傳入文件名(不含路徑)。 – wasatchwizard 2013-09-24 19:17:22
是否遇到過這個問題,並且必須自己解決,因爲這些使用對我的需求非常重要。 我需要找到重複的URL和行的順序是相關的,所以它需要被保留。文本行不應該包含任何雙引號,不應該很長,並且不能使用排序。
因此我這樣做:
setlocal enabledelayedexpansion
type nul>unique.txt
for /F "tokens=*" %%i in (list.txt) do (
find "%%i" unique.txt 1>nul
if !errorlevel! NEQ 0 (
echo %%i>>unique.txt
)
)
輔助:如果文本中包含雙引號,則FIND需要在這篇文章中描述使用過濾設置變量:Escape double quotes in parameter
因此,而不是:
find "%%i" unique.txt 1>nul
它會更喜歡:
set test=%%i
set test=!test:"=""!
find "!test!" unique.txt 1>nul
因此,find會看起來像查找「」「什麼」「」文件和%%我將保持不變。
我使用了一個假的「陣」來完成這項
@echo off
:: filter out all duplicate ip addresses
REM you file would take place of %1
set file=%1%
if [%1]==[] goto :EOF
setlocal EnableDelayedExpansion
set size=0
set cond=false
set max=0
for /F %%a IN ('type %file%') do (
if [!size!]==[0] (
set cond=true
set /a size="size+1"
set arr[!size!]=%%a
) ELSE (
call :inner
if [!cond!]==[true] (
set /a size="size+1"
set arr[!size!]=%%a&& ECHO > NUL
)
)
)
break> %file%
:: destroys old output
for /L %%b in (1,1,!size!) do echo !arr[%%b]!>> %file%
endlocal
goto :eof
:inner
for /L %%b in (1,1,!size!) do (
if "%%a" neq "!arr[%%b]!" (set cond=true) ELSE (set cond=false&&goto :break)
)
:break
利用標籤內環路的特定於cmd.exe的東西,是我已經成功嵌套for循環的唯一出路在彼此之內。基本上,這比較了每個作爲分隔符傳遞的新值,如果沒有匹配,那麼程序會將該值添加到內存中。當它完成它會破壞目標文件的內容,並具有獨特的琴絃
批處理文件下面你想要什麼取代他們:
@echo off
setlocal EnableDelayedExpansion
set "prevLine="
for /F "delims=" %%a in (theFile.txt) do (
if "%%a" neq "!prevLine!" (
echo %%a
set "prevLine=%%a"
)
)
如果你需要一個更有效的方法,嘗試這種分批JScript混合腳本,開發爲篩選器,即類似於Unix的uniq
程序。與.bat擴展名保存它,像uniq.bat
:
@if (@CodeSection == @Batch) @then
@CScript //nologo //E:JScript "%~F0" & goto :EOF
@end
var line, prevLine = "";
while (! WScript.Stdin.AtEndOfStream) {
line = WScript.Stdin.ReadLine();
if (line != prevLine) {
WScript.Stdout.WriteLine(line);
prevLine = line;
}
}
這兩個方案是從this post複製。
純批量 - 3條生產線。
@ECHO OFF
SETLOCAL
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
FOR /f "delims=" %%a IN (q34223624.txt) DO SET $%%a=Y
(FOR /F "delims=$=" %%a In ('set $ 2^>Nul') DO ECHO %%a)>u:\resultfile.txt
GOTO :EOF
如果數據不包含批次具有敏感性的字符,則可以愉快地工作。
「q34223624.txt」,因爲問題34223624包含在此數據
1.1.1.1
1.1.1.1
1.1.1.1
1.2.1.2
1.2.1.2
1.2.1.2
1.3.1.3
1.3.1.3
1.3.1.3
上它完美的作品。
- 1. 批處理腳本 - 在文件中刪除重複的令牌
- 2. 批處理腳本 - 刪除從文本文件的特定行
- 3. 批處理文件腳本刪除文件夾中重複的文件
- 4. 從批處理文件中刪除文本行
- 5. 批處理腳本刪除「重複」的文件
- 6. 批處理腳本刪除文本文件中的特定行
- 7. 從批處理文件中的文件中刪除行
- 8. 批處理文件刪除文本文件的前3行
- 9. 使用批處理刪除文本文件中的某一行
- 10. 批處理文件刪除文本文件中的連續文本行
- 11. 刪除文本文件中的批處理文件變量
- 12. Linux刪除文件批處理腳本
- 13. 批處理腳本刪除文件
- 14. 批處理:從文本文件中刪除所有空格?
- 15. 批處理:刪除文本文件末尾的換行符?
- 16. 批處理腳本刪除文本文件中的字符
- 17. 批處理文件刪除文件夾
- 18. 命令行:從批處理文件中的回顯數據中刪除文本
- 19. 使用批處理腳本刪除文件中的特定行
- 20. 批量刪除批處理文件
- 21. 批處理文件,以刪除文件夾中的重複Shotcut鏈接
- 22. 從文本文件中刪除空行和重複的行
- 23. 使用Windows批處理文件複製文件並刪除重複項
- 24. 從批處理文件中的文本文件中過濾行
- 25. 批處理刪除文本文件中的尾部空白
- 26. Windows批處理腳本,從文件名中刪除括號中的文本?
- 27. 如何通過批處理從文本文件中刪除文本
- 28. 從文件中刪除XML標記與批處理文件
- 29. 批處理文件:從.tsv文件中刪除回車
- 30. 顯示從文本文件中的行批處理文件
Ran into finstr搜索字符串太長。 – 2016-03-28 07:47:36
@Dreadedsemicolon - 是的,我不認爲如果由於FINDSTR限制,任何行超過長度511(XP上的127),第二個選項將失敗。 – dbenham 2016-03-28 12:49:06