Có thể xóa các hàng trùng lặp khỏi một tệp văn bản không? Nếu có, làm thế nào?Hàng loạt để xóa các hàng trùng lặp khỏi tệp văn bản
Trả lời
Chắc chắn có thể, nhưng giống như hầu hết các tệp văn bản xử lý với hàng loạt, nó không phải là đẹp, và nó không phải là đặc biệt nhanh.
Giải pháp này bỏ qua trường hợp khi tìm kiếm trùng lặp và sắp xếp các dòng. Tên của tệp được chuyển thành đối số thứ nhất và duy nhất cho tập lệnh batch.
@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%"
Giải pháp này phân biệt chữ hoa chữ thường và để các dòng theo thứ tự ban đầu (trừ các khóa trùng lặp). Một lần nữa tên của tập tin được truyền vào như đối số đầu tiên và duy nhất.
@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
Cả hai giải pháp trên dòng trống dải. Tôi không nghĩ rằng các dòng trống đáng được bảo tồn khi nói về các giá trị riêng biệt.
Tôi đã sửa đổi cả hai giải pháp để tắt tùy chọn FOR/F "EOL" để tất cả các dòng không trống được giữ nguyên, bất kể ký tự thứ nhất là gì. Mã được sửa đổi đặt tùy chọn EOL thành ký tự linefeed.
giải pháp mới 2016/04/13: JSORT.BAT
Bạn có thể sử dụng của tôi JSORT.BAT hybrid JScript/batch utility để có hiệu quả sắp xếp và loại bỏ dòng trùng lặp với một lót đơn giản (cộng với một MOVE để ghi đè lên file gốc với kết quả cuối cùng). JSORT là tập lệnh thuần túy chạy tự nhiên trên bất kỳ máy Windows nào từ XP trở đi.
@jsort file.txt /u >file.txt.new
@move /y file.txt.new file.txt >nul
bạn có thể sử dụng uniq
http://en.wikipedia.org/wiki/Uniq từ UnxUtilshttp://sourceforge.net/projects/unxutils/
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"
này nên làm việc giống hệt nhau. Ví dụ dbenham đó dường như quá cứng rắn đối với tôi, vì vậy, đã thử nghiệm giải pháp của riêng tôi. sử dụng ví dụ: filedup.cmd filename.ext
Chỉ cần một FYI: Câu lệnh 'set' đầu tiên sẽ không hoạt động. Tôi đã thấy% CD% bị lỗi và/hoặc bị ghi đè nhiều lần! Bạn nên sử dụng nó thay vì 'set" file =% ~ dpnx1 "'. Các chữ cái trong% 1 được định nghĩa là: d = drive, p = path, n = filename (không có phần mở rộng), x = extension. Điều này làm việc cho đối số đầu tiên ngay cả khi bạn chỉ chuyển vào tên tệp (không có đường dẫn). – wasatchwizard
Đã gặp phải vấn đề này và phải tự khắc phục sự cố vì việc sử dụng là do nhu cầu của tôi. Tôi cần phải tìm URL trùng lặp và thứ tự các dòng có liên quan để nó cần được bảo tồn. Các dòng văn bản không được chứa bất kỳ dấu ngoặc kép nào, không nên dài và sắp xếp không thể được sử dụng.
Vì vậy, tôi đã làm điều này:
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
)
)
phụ: nếu văn bản có chứa dấu ngoặc kép thì FIND cần phải sử dụng một biến thiết lập lọc như mô tả trong bài viết này: Escape double quotes in parameter
Vì vậy, thay vì:
find "%%i" unique.txt 1>nul
nó sẽ được nhiều hơn như:
set test=%%i
set test=!test:"=""!
find "!test!" unique.txt 1>nul
Do đó, tìm sẽ giống như tìm "" "tệp" "nào và %% i sẽ không thay đổi.
Tôi đã sử dụng một "mảng" giả để thực hiện điều này
@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
việc sử dụng các nhãn cho các vòng lặp bên trong là một cái gì đó cụ thể để cmd.exe và là cách duy nhất tôi đã làm tổ thành công cho vòng bên trong nhau. Về cơ bản, điều này so sánh mỗi giá trị mới đang được chuyển như một dấu tách và nếu không có kết quả phù hợp thì chương trình sẽ thêm giá trị vào bộ nhớ. Khi nó được thực hiện nó sẽ phá hủy các nội dung tập tin mục tiêu và thay thế bằng các dây độc đáo
Các tập tin hàng loạt dưới đây làm những gì bạn muốn:
@echo off
setlocal EnableDelayedExpansion
set "prevLine="
for /F "delims=" %%a in (theFile.txt) do (
if "%%a" neq "!prevLine!" (
echo %%a
set "prevLine=%%a"
)
)
Nếu bạn cần một phương pháp hiệu quả hơn, hãy thử Batch- này Tập lệnh lai JScript được phát triển dưới dạng bộ lọc , tương tự như chương trình Unix uniq
. Lưu tiện ích mở rộng .bat, như 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;
}
}
Cả hai chương trình được sao chép từ this post.
Hàng loạt tinh khiết - 3 dòng hiệu quả.
@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
Làm việc vui vẻ nếu dữ liệu không chứa các ký tự có hàng loạt có độ nhạy.
"q34223624.txt" vì câu hỏi 34.223.624 chứa dữ liệu này
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
mà nó hoạt động hoàn hảo.
- 1. Xóa các dòng trùng lặp khỏi tệp văn bản?
- 2. Xóa các hàng trùng lặp
- 3. Cách xóa hàng trùng lặp khỏi ma trận
- 4. Cách xóa hàng trùng lặp khỏi tuyên bố công đoàn
- 5. Xóa hàng trùng lặp trong Django DB
- 6. Xóa các hàng trùng lặp khỏi một tệp lớn trong Python
- 7. Xóa nhiều hàng trùng lặp trong bảng
- 8. Cách hiệu quả nhất để xóa tất cả các hàng trùng lặp khỏi bảng?
- 9. Tệp hàng loạt để xóa 3 dòng đầu tiên của một tệp văn bản
- 10. Xóa hàng loạt số lượng tệp lớn
- 11. R, có điều kiện xóa các hàng trùng lặp
- 12. Xóa hàng trùng lặp và giữ một hàng
- 13. SQL Xóa hầu hết các hàng trùng lặp
- 14. Xóa các hàng trùng lặp (không xóa tất cả các bản sao)
- 15. Xóa các hàng trùng lặp để lại hàng cũ nhất Chỉ có?
- 16. Tải lên hàng loạt nhiều tệp văn bản vào MediaWiki
- 17. Xóa các hàng "trùng lặp" trong SQL Server 2010
- 18. Cách xóa các hàng trùng lặp và cập nhật bảng
- 19. Làm thế nào để xóa hoàn toàn trùng lặp hàng
- 20. In các kết quả tệp hàng loạt vào một tệp văn bản
- 21. truy vấn sql để xóa chỉ một hàng trùng lặp
- 22. Xóa trùng lặp khỏi TStringList
- 23. Hàng loạt và vòng lặp
- 24. Chọn một hàng từ hàng trùng lặp
- 25. Xóa các mục trùng lặp khỏi LEFT OUTER JOIN
- 26. xóa hàng loạt trong GIT?
- 27. Làm cách nào để so sánh hai bảng và xóa các hàng trùng lặp trong SQL?
- 28. Xử lý hàng loạt văn bản thành ngữ trong Emacs?
- 29. xóa các hàng trùng lặp và cần giữ một hàng từ tất cả chúng trong mysql
- 30. Xóa hàng loạt (cắt ngắn và xóa)
Được chuyển thành chuỗi tìm kiếm finstr quá dài. –
@Dreadedsemicolon - Có, tôi không nghĩ đến việc lựa chọn thứ 2 thất bại nếu bất kỳ dòng nào vượt quá chiều dài 511 (127 trên XP) do các giới hạn FINDSTR. – dbenham