Mit Batchdatei aus einer .txt alle doppelten Zeilen (Duplikate) komplett löschen
Hallo Admins,
ich müsste mittels Batchdatei (!) folgendes Problem lösen:
Eine Textdatei Daten.txt hat folgenden Inhalt:
11111111
22222222
33333333
44444444
55555555
55555555
22222222
Nun sollen alle Zeilen, die doppelt vorkommen, KOMPLETT gelöscht werden - oder alternativ: alle Zeilen, die einmal vorkommen, in eine neue Datei geschrieben werden. Das Ergebnis soll jedenfalls so aussehen:
11111111
33333333
44444444
Mit folgendem Code werden zumindest alle Duplikate gelöscht:
Doch das Ergebnis sieht so aus:
11111111
22222222
33333333
44444444
55555555
Das war allerdings nicht das was ich erreichen wollte, siehe oben.
Hat jemand eine Idee für dieses knifflige Problem? Ich komme da nicht so recht weiter ... Und wie gesagt, es müsste mittels Batchdatei laufen.
Vielen Dank & Gruß
ich müsste mittels Batchdatei (!) folgendes Problem lösen:
Eine Textdatei Daten.txt hat folgenden Inhalt:
11111111
22222222
33333333
44444444
55555555
55555555
22222222
Nun sollen alle Zeilen, die doppelt vorkommen, KOMPLETT gelöscht werden - oder alternativ: alle Zeilen, die einmal vorkommen, in eine neue Datei geschrieben werden. Das Ergebnis soll jedenfalls so aussehen:
11111111
33333333
44444444
Mit folgendem Code werden zumindest alle Duplikate gelöscht:
@echo off & setlocal
set "Datei=Daten.txt"
set "Bak=.bak"
set /a LineNo=0
move "%Datei%" "%Datei%%Bak%"
copy nul "%Datei%">nul
for /f "usebackq delims=" %%i in ("%Datei%%Bak%") do set "Zeile=%%i" & call :ProcessLine
del "%Datei%%Bak%"
goto :eof
:ProcessLine
set /a LineNo+=1
echo Validiere Zeile %LineNo% ...
findstr /b /c:"%Zeile:~,8%" "%Datei%">nul || >>"%Datei%" echo %Zeile%
goto :eof
Doch das Ergebnis sieht so aus:
11111111
22222222
33333333
44444444
55555555
Das war allerdings nicht das was ich erreichen wollte, siehe oben.
Hat jemand eine Idee für dieses knifflige Problem? Ich komme da nicht so recht weiter ... Und wie gesagt, es müsste mittels Batchdatei laufen.
Vielen Dank & Gruß
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 116968
Url: https://administrator.de/contentid/116968
Ausgedruckt am: 14.11.2024 um 21:11 Uhr
6 Kommentare
Neuester Kommentar
Hallo alfabravo und willkommen im Forum!
Du könntest es mit einem zweiten Durchlauf versuchen - im Prinzip etwa so:
Grüße
bastla
Du könntest es mit einem zweiten Durchlauf versuchen - im Prinzip etwa so:
@echo off & setlocal
set "Datei=Daten.txt"
set "Bak=.bak"
set "TempDatei=%temp%\TempDatei.txt"
set "Duplikate=%temp%\Duplikate.txt"
set /a LineNo=0
move "%Datei%" "%Datei%%Bak%"
copy nul "%Duplikate%">nul
copy nul "%TempDatei%">nul
for /f "usebackq delims=" %%i in ("%Datei%%Bak%") do set "Zeile=%%i" & call :ProcessLine
for /f "usebackq delims=" %%i in ("%TempDatei%") do set "Zeile=%%i" & call :ProcessLine2
del "%Datei%%Bak%"
del "%Duplikate%"
del "%TempDatei%"
goto :eof
:ProcessLine
set /a LineNo+=1
echo Validiere Zeile %LineNo% ...
findstr /b /c:"%Zeile:~,8%" "%TempDatei%">nul && >>"%Duplikate%" echo %Zeile% || >>"%TempDatei%" echo %Zeile%
goto :eof
:ProcessLine2
findstr /b /c:"%Zeile:~,8%" "%Duplikate%">nul || >>"%Datei%" echo %Zeile%
goto :eof
bastla
Hallo bastla,
der findstr /V /G:datei wird doch immer wieder unterschätzt
Gruß
LotPings
der findstr /V /G:datei wird doch immer wieder unterschätzt
:: RemoveDupes.cmd :::::::::::::::::::::::::::::::::::::::::::::::::
@echo off & setlocal EnableDelayedExpansion
set "Datei=test.txt"
set "Bak=.bak"
set "Duplikate=%temp%\Duplikate.txt"
move "%Datei%" "%Datei%%Bak%"
copy nul "%Duplikate%">nul
If defined LastLine Set "LastLine="
for /f "delims=" %%A in ('Sort ^<"%Datei%%Bak%" ') do (
If /i "!LastLine!"=="%%A" (Echo/%%A)>>"%Duplikate%"
set "LastLine=%%A"
)
findstr /V /G:"%Duplikate%" <"%Datei%%Bak%" >"%Datei%"
del "%Duplikate%"
Gruß
LotPings
@77559
Grüße
bastla
der findstr /V /G:datei wird doch immer wieder unterschätzt
Mitnichten - hatte es (allerdings ohne Umleitung für die Eingabe, sondern mit direkter Angabe) versucht und weiß noch immer nicht, warum es nicht so wie ich wollte - deshalb die weniger elegante, aber immerhin funktionierende Version ...Grüße
bastla
Moin LotPings,
da hätte ich aber noch einen Verbesserungsvorschlag....
In (mindestens) zwei Fällen wird sich der Starter Deines Schnipsels eventuell ein kleines bisschen ärgern:
In diesen beiden und allen anderen Fällen, in denen FindStr abgrätscht hinterlässt der obige Batch eine Fehlermeldung auf dem Bildschirm und eine Originaldatei (bzw. Datei mit dem Namen der Originaldatei) in der Größe von 0 Byte.
Deshalb würde ich noch eine minimale Fehlerbehandlung einbauen:
Der Kurztest am CMD-Prompt.
Grüße
Biber
da hätte ich aber noch einen Verbesserungsvorschlag....
In (mindestens) zwei Fällen wird sich der Starter Deines Schnipsels eventuell ein kleines bisschen ärgern:
- wenn eine Zeile in der Textdatei enthalten ist, die der FindStr.exe irgendwie zu lang zum Suchen erscheint (führt zu Fehler: "FINDSTR: Suchzeichenfolge zu lang.")
- oder, viel wahrscheinlicher: es gibt nun gar keine Duplikate in der Originaldatei. (Führt zu Fehler: "FINDSTR: Keine Suchzeichenfolge")
In diesen beiden und allen anderen Fällen, in denen FindStr abgrätscht hinterlässt der obige Batch eine Fehlermeldung auf dem Bildschirm und eine Originaldatei (bzw. Datei mit dem Namen der Originaldatei) in der Größe von 0 Byte.
Deshalb würde ich noch eine minimale Fehlerbehandlung einbauen:
:: RemoveDups.cmd :::::::::::::::::::::::::::::::::::::::::::::::::
@echo off & setlocal EnableDelayedExpansion
set "Datei=duptest.txt"
set "Bak=.bak"
set "Duplikate=%temp%\Duplikate.txt"
move "%Datei%" "%Datei%%Bak%"
copy nul "%Duplikate%">nul
If defined LastLine Set "LastLine="
for /f "delims=" %%A in ('Sort ^<"%Datei%%Bak%" ') do (
If /i "!LastLine!"=="%%A" (Echo/%%A)>>"%Duplikate%"
set "LastLine=%%A"
)
findstr /V /G:"%Duplikate%" <"%Datei%%Bak%" >"%Datei%"
if errorlevel 1 (
Echo Fehler aufgetreten - Originaldatei wird wiederhergestellt.
dir "%datei%"|find /i "%datei%" & type "%datei%" & pause
move "%Datei%%Bak%" "%Datei%"
)
del "%Duplikate%"
Der Kurztest am CMD-Prompt.
>type duptest.txt
11111111
33333333
44444444
>e:\schnipsel\RemoveDups.cmd
FINDSTR: Keine Suchzeichenfolge
Fehler aufgetreten - Originaldatei wird wiederhergestellt.
28.05.09 08:27 0 duptest.txt
Drücken Sie eine beliebige Taste . . .
>dir duptest.txt|find "duptest"
28.05.09 08:15 30 duptest.txt
Grüße
Biber
Immer gerne gesehen
Eine Umkehrung der Logik sscheint mir aber sinnvoller,
die neue Datei ersetzt nur dann die alte wenn kein Fehler aufgetreten ist.
Extra ein bisschen kryptischer und kürzer aber auch komfortabler.
Gruß
LotPings
Eine Umkehrung der Logik sscheint mir aber sinnvoller,
die neue Datei ersetzt nur dann die alte wenn kein Fehler aufgetreten ist.
Extra ein bisschen kryptischer und kürzer aber auch komfortabler.
:: RemoveDupes.cmd :::::::::::::::::::::::::::::::::::::::::::::::::
@cls&echo off&setlocal EnableDelayedExpansion
if Not Exist \"%~1\" (Echo Usage: %~nx0 Dubletten.txt&Pause&Exit /b 0)
(copy nul \"%~f1.Dup%\">nul)&set cnt=0&If defined LL Set \"LL=\"
for /f \"delims=\" %%A in (\'Sort ^<\"%~f1\" \') do (
If /i \"!LL!\"==\"%%A\" (Echo/%%A)>>\"%~f1.Dup\"
set \"LL=%%A\"&Set /A cnt+=1)
IF %cnt% GTR 0 findstr /V /G:\"%~f1.Dup\" <\"%~f1\" >\"%~f1.new\"&&(Move /Y \"%~f1.new\" \"%~f1\">NUL)||Echo Fehler! %~f0 unverändert
For %%A in (new Dup) do del \"%~f1.%%A\" >NUL 2>&1
Gruß
LotPings