web-gelistirme-sc.com

Metin dosyasından yinelenen satırları kaldırmak için toplu iş

Bir metin dosyasından yinelenen satırları kaldırmak mümkün müdür? Evet ise nasıl?

10
Rocshy

Tabii ki, ancak çoğu metin dosyası toplu işlem ile işleme gibi, hoş değil ve özellikle hızlı değil.

Bu çözüm, kopyaları ararken küçük harfleri yoksayar ve satırları sıralar. Dosyanın adı toplu iş komut dosyasının ilk ve tek argümanı olarak iletilir.

@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%"

Bu çözüm büyük/küçük harfe duyarlıdır ve satırları orijinal sırayla bırakır (tabii ki kopyalar hariç). Yine dosyanın adı 1. ve tek argüman olarak geçildi.

@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%"


DÜZENLE

Her iki çözümde de boş satırları soyun. Farklı değerlerden bahsederken boş çizgilerin korunmaya değeceğini düşünmedim.

FOR/F "EOL" seçeneğini devre dışı bırakmak için her iki çözümü de değiştirdim, böylece boş olmayan tüm satırların, ilk karakterin ne olduğuna bakılmaksızın korunmasını sağladım. Değiştirilen kod, EOL seçeneğini satır besleme karakterine ayarlar.


Yeni çözüm 2016-04-13: JSORT.BAT

Basit bir tek astar ile yinelenen satırları verimli bir şekilde sıralamak ve kaldırmak için JSORT.BAT hibrit JScript/toplu iş yardımcı programını kullanabilirsiniz (artı nihai sonucun orijinal dosyanın üzerine yazmak için bir MOVE). JSORT, herhangi bir Windows makinesinde yerel olarak çalışan XP tarihinden itibaren çalışan bir komut dosyasıdır.

@jsort file.txt /u >file.txt.new
@move /y file.txt.new file.txt >nul
13
dbenham
9
PA.
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"

Bu tamamen aynı şekilde çalışması gerekir. Bu dbenham örneği benim için çok zor görünüyordu, bu yüzden kendi çözümümü denedim. kullanım ex .: filedup.cmd dosyaadı.ext

3
genetix

Aşağıdaki toplu iş dosyası ne istiyorsan onu yap:

@echo off
setlocal EnableDelayedExpansion
set "prevLine="
for /F "delims=" %%a in (theFile.txt) do (
   if "%%a" neq "!prevLine!" (
      echo %%a
      set "prevLine=%%a"
   )
)

Daha verimli bir yönteme ihtiyacınız varsa, bir filter olarak geliştirilen bu Batch-JScript karma komut dosyasını deneyin, yani Unix uniq programına benzer. uniq.bat gibi bir .bat uzantısı ile kaydedin:

@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;
   }
}

Her iki program da bu yazıdan kopyalandı.

2
Aacini

Saf parti - 3 etkili hat.

@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

Veriler toplu işin hassas olduğu karakterleri içermiyorsa mutlu çalışır.

"q34223624.txt" çünkü 34223624 sorusu bu verileri içeriyor

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ükemmel çalıştığı.

2
Magoo

Bunu gerçekleştirmek için sahte bir "dizi" kullandım

@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

iç döngü için etiketin kullanımı cmd.exe'ye özgü bir şeydir ve birbirimdeki döngüler için yuvalamayı başarılı bir şekilde yaptım. Temel olarak, bu sınırlayıcı olarak iletilen her yeni değeri karşılaştırır ve eşleşme yoksa, program değeri belleğe ekler. Tamamlandığında, hedef dosya içeriğini yok edecek ve bunları benzersiz dizelerle değiştirecektir.

1
user4301289

Bu sorunu karşıladım ve kullanımı benim ihtiyacım için özel olduğu için kendim çözmek zorunda kaldım. Yinelenen URL’leri bulmam gerekiyordu ve satırların sırası önemliydi, bu yüzden de korunması gerekiyordu. Metin satırları çift tırnak içermemeli, çok uzun olmamalı ve sıralama kullanılamaz.

Böylece bunu yaptım:

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
    )
)

Yardımcı: metin çift tırnak içeriyorsa, FIND bu yayında açıklanan şekilde filtrelenmiş bir set değişkeni kullanmalıdır: parametrede çift tırnaktan kaçış

Yani yerine:

find "%%i" unique.txt 1>nul

daha fazla olurdu:

set test=%%i
set test=!test:"=""!
find "!test!" unique.txt 1>nul

Böylece bul "" "ne" "" bul bul gibi görünecek ve %% ben değişmeyecek.

0
JasonXA