2012-07-27 13 views

उत्तर

9

निश्चित रूप से बैच के साथ अधिकांश टेक्स्ट फ़ाइल प्रोसेसिंग की तरह, यह सुंदर नहीं है, और यह विशेष रूप से तेज़ नहीं है।

यह समाधान डुप्लीकेट की तलाश करते समय मामले को अनदेखा करता है, और यह लाइनों को टाइप करता है। फ़ाइल का नाम बैच स्क्रिप्ट के लिए पहला और एकमात्र तर्क के रूप में पारित किया गया है।

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


संपादित

पट्टी रिक्त लाइनों के ऊपर दोनों समाधान। मुझे नहीं लगता था कि अलग-अलग मूल्यों के बारे में बात करते समय रिक्त रेखाएं संरक्षित थीं।

मैंने फोर/एफ "ईओएल" विकल्प को अक्षम करने के लिए दोनों समाधानों को संशोधित किया है ताकि सभी गैर-खाली रेखाएं संरक्षित हों, भले ही पहला चरित्र क्या हो। संशोधित कोड ईओएल विकल्प को एक लाइनफेड वर्ण में सेट करता है।


नए समाधान 2016/04/13: JSORT.BAT

तुम मेरे JSORT.BAT hybrid JScript/batch utility कुशलतापूर्वक तरह और एक सरल एक लाइनर (प्लस एक चाल के साथ डुप्लीकेट लाइनों को हटाने के मूल फ़ाइल अधिलेखित करने के लिए उपयोग कर सकते अंतिम परिणाम के साथ)। जेएसओआर शुद्ध स्क्रिप्ट है जो एक्सपी ऑनवर्ड से किसी भी विंडोज मशीन पर मूल रूप से चलता है।

@jsort file.txt /u >file.txt.new 
@move /y file.txt.new file.txt >nul 
+0

फिनस्ट्रेट सर्च स्ट्रिंग में दौड़ बहुत लंबा है। –

+1

@Dreadedsemicolon - हां, मैंने यह उल्लेख नहीं किया कि दूसरा विकल्प विफल रहता है यदि FINDSTR सीमाओं के कारण कोई लाइन लंबाई 511 (127 पर 127) से अधिक हो जाती है। – dbenham

3
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 उदाहरण मेरे लिए बहुत कट्टर लग रहा था, तो, मेरे अपने समाधान का परीक्षण किया। उपयोग पूर्व .: fileup.cmd filename.ext

+0

बस एक एफवाईआई: पहला 'सेट' कथन हमेशा काम नहीं करेगा। मैंने% सीडी% असफल देखा है और/या कई बार अधिलेखित हो गया है! आपको इसके बजाय 'सेट' फ़ाइल =% ~ dpnx1 "' का उपयोग करना चाहिए। % 1 में अक्षरों को परिभाषित किया गया है: डी = ड्राइव, पी = पथ, एन = फ़ाइल नाम (एक्सटेंशन के बिना), x = एक्सटेंशन। यह पहली तर्क के लिए भी काम करता है जब भी आप केवल फ़ाइल नाम (पथ के बिना) में गुजरते हैं। – wasatchwizard

0

इस मुद्दे पर आया था और इसे स्वयं हल करना था क्योंकि उपयोग मेरी आवश्यकता के लिए कण था। मुझे डुप्लिकेट यूआरएल खोजने की जरूरत है और लाइनों का क्रम प्रासंगिक था इसलिए इसे संरक्षित करने की आवश्यकता थी। पाठ की रेखाओं में कोई डबल कोट नहीं होना चाहिए, बहुत लंबा नहीं होना चाहिए और सॉर्टिंग का उपयोग नहीं किया जा सकता है।

इस प्रकार मैं इस किया था:

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

सहायक: Escape double quotes in parameter

तो बजाय: पाठ में दोहरे उद्धरण चिह्न करता है तो FIND इस पोस्ट में वर्णित के रूप में फ़िल्टर किए गए सेट चर का उपयोग करने की जरूरत है:

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

यह होगा और अधिक की तरह:

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

इस प्रकार खोज "" "फाइल और %% की तरह दिखने लगेगा, मैं अपरिवर्तित हूं।

1

मैं एक नकली "सरणी" का इस्तेमाल किया है इस

@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 लिए विशिष्ट है और एक ही रास्ता मैं छोरों के लिए सफल नेस्टिंग किया गया है है एक दूसरे के भीतर। असल में यह प्रत्येक नए मान की तुलना करता है जिसे एक डिलीमीटर के रूप में पारित किया जा रहा है और यदि कोई मिलान नहीं है तो प्रोग्राम मूल्य को स्मृति में जोड़ देगा। जब यह किया जाता है यह लक्ष्य फ़ाइलों सामग्री को नष्ट करने और उन्हें अद्वितीय तार

2

बैच फ़ाइल नीचे कि आप क्या चाहते हो के साथ बदल देगा:

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

आप एक अधिक कुशल पद्धति की जरूरत है, इस Batch- कोशिश जेस्क्रिप्ट हाइब्रिड स्क्रिप्ट जिसे फ़िल्टर के रूप में विकसित किया गया है, जो यूनिक्स 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 से नकल कर रहे थे।

2

शुद्ध बैच - 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" क्योंकि सवाल 34,223,624 इस डेटा

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 

जिस पर यह पूरी तरह से काम करता है निहित।

संबंधित मुद्दे