2013-04-05 2 views
2

Я пытаюсь выполнить пакетный процесс в Notepad ++, который будет подсчитывать количество повторяющихся строк из выбранного текста.Пакетный цикл через файл

До сих пор у меня есть Notepad ++ работает отлично

NPE_CONSOLE v+ 
CLS 
ECHO $(CURRENT_WORD) 
CON_SAVETO "H:\tmp.txt" 
NPE_CONSOLE v- 

This сценарии сохраняет выбранный текст в tmp.txt с единственной проблемой является она включает в себя, в нижней части, CON_SAVETO "H:\tmp.txt", но я могу жить с этим на данный момент.

EDIT: Кроме того, я не думаю, что Notepad ++ это вопрос здесь, так как я пытаюсь запустить пакетный файл из cmd линии и получить те же ошибки/проблемы. Я также попытался установить файл tmp.txt вручную и все те же проблемы.

Мой командный файл является то, что вызывает вопросы:

::@ECHO OFF 
CD "H:\" 
SET counter=0 
SET prev=a 

FOR /F "tokens=*" %%L IN (tmp.txt) DO (
    SET blnOut=0 
    SET curLine="%%L" 

    IF /I %prev%==%curLine% (
     SET counter=%counter%+1 
     SET blnOut=1 
    ) 
    IF %blnOut%==0 (
     IF %prev%==a (
      SET counter=%counter%+1 
      SET blnOut=1 
     ) 
     IF %blnOut%==0 (
      ECHO %curLine%- %counter% 
      SET counter=1 
     ) 
    ) 
    SET prev=%curLine% 
) 

Я пробовал все, что я могу думать, в том числе откола процесса в функцию, но я продолжаю получать ошибки как Unexpected) или, если это выполняется, он не прокручивает файл.

В настоящее время это tmp.txt:

1 
2 
3 
4 
5 
6 
7 
8 
1 
4 
5 
8 
4 
3 
4 
4 
5 

Так Ideal выход:

1 - 2 
2 - 1 
3 - 2 
4 - 5 
5 - 3 
6 - 1 
7 - 1 
8 - 2 
+0

Считаете ли вы, что блокнот ++ вызывает это поведение? – Endoro

+0

Я не думаю, что проблема с Notepad ++ здесь, хотя я включил код в том случае, если кто-то может подтвердить или опровергнуть это. Обновленный вопрос, чтобы лучше объяснить это. –

+0

Как вы называете свой командный файл (и какие параметры вы проходите); то, что разрешает '% 1' в этом примере? –

ответ

4
@ECHO OFF 
SETLOCAL enabledelayedexpansion 
FOR %%i IN (prev) DO SET "%%i=" 
FOR /f "delims=" %%i IN ('sort ^<temp.txt') DO (
IF DEFINED prev (
    IF "!prev!"=="%%i" (SET /a count+=1) ELSE (
    ECHO !prev! - !count! 
    SET "prev=" 
) 
) 
IF NOT DEFINED prev (
    SET prev=%%i 
    SET /a count=1 
) 
) 
ECHO %prev% - %count% 

Вот моя версия. Сортируйте входной файл, чтобы группировать подобные строки вместе, а затем, когда содержимое строки изменяется, отображает предыдущее содержимое и подсчитывает и перезаписывает счетчик и записывает предыдущую строку.

+0

+1 Отличная идея с использованием 'sort'. Это более эффективно, чем [мое решение] (http://stackoverflow.com/a/15842198/1683264) Я думаю. Тем не менее, он не будет поддерживать порядок. Не уверен, что это важно. – rojo

+0

приятный ++! \t @@@@@@@@@@@@@ – Endoro

+0

Приятно, если это почти копия-паста. (пришлось менять 'temp' на' tmp' и снова вставлять 'CD'), но фантастически. Работает как магия. –

2

Вы не можете установить переменную среды и использовать его в той же for цикла с использованием % синтаксиса, вы необходимо использовать задержанное расширение и использовать синтаксис !.

Я не проверял, но попробовать это:

::@ECHO OFF 
SETLOCAL ENABLEDELAYEDEXPANSION 
CD "H:\" 
SET counter=0 
SET prev=a 

FOR /F "tokens=*" %%L IN (tmp.txt) DO (
    SET blnOut=0 
    SET curLine="%%L" 

    IF /I !prev!==!curLine! (
     SET counter=!counter!+1 
     SET blnOut=1 
    ) 
    IF !blnOut!==0 (
     IF !prev!==a (
      SET counter=!counter!+1 
      SET blnOut=1 
     ) 
     IF !blnOut!==0 (
      ECHO !curLine!- !counter! 
      SET counter=1 
     ) 
    ) 
    SET prev=!curLine! 
) 

Или переместить тело цикла for в подпрограмму.

0

Вы сделали больше ошибок, я бы сказал сейчас. Посмотрите на delayed expansion, if /?, for /?, set /? и все прочее ... пакетном

@ECHO OFF &setlocal enabledelayedexpansion 
CD /d "H:\" 
SET counter=0 
SET prev=a 

FOR /F "tokens=*" %%L IN (tmp.txt) DO (
    SET blnOut=0 
    SET "curLine=%%L" 

    IF /I "!prev!"=="!curLine!" (
     SET /a counter+=1 
     SET blnOut=1 
    ) 
    IF "!blnOut!"=="0" (
     IF "!prev!"=="a" (
      SET /a counter+=1 
      SET blnOut=1 
     ) 
     IF "!lnOut!"=="0" (
      ECHO !curLine!- !counter! 
      SET counter=1 
     ) 
    ) 
    SET "prev=!curLine!" 
) 

Ваш код не имеет смысла, если вы postet содержание tmp.txt правильно.

+0

«Ваш код не имеет смысла, если вы правильно разместите содержимое« tmp.txt ».» Этот комментарий бесполезен, поскольку он не объясняет, что не так, и почему это неправильно. –

+0

Извините, но ваши знания в партии настолько бедны, и жизнь коротка. – Endoro

1

Вот моя идея для немного другого направления. Он выводит ожидаемые результаты. Выход не сортируется; сохраняется исходный порядок строк.

@ECHO OFF 
setlocal enabledelayedexpansion 

set filename=h:\tmp.txt 
set idx=0 

:: build array of unique lines 
FOR /F "usebackq delims=" %%I IN ("%filename%") DO (

    rem :: if dupe line not already processed 
    2>NUL set line | findstr /r /c:"^line\[[0-9]*\]=%%I$" >NUL || (

     rem :: add it to the array 
     set "line[!idx!]=%%I" 
     set /a "idx+=1" 
    ) 
) 

:: For each unique line 
set /a "idx-=1" 
for /L %%I in (0,1,%idx%) do (

    rem :: Echo the line contents without a line break 
    set /p "=!line[%%I]! - "<NUL 

    rem :: use find /c to count the instances of that line. 
    findstr /b /e /c:"!line[%%I]!" "%filename%" | find /c "!line[%%I]!" 
) 
3

Пакетная программа ниже делать то, что вы хотите в более быстром способе, пока линии не содержат определенные специальные символы Batch:

@echo off 
setlocal EnableDelayedExpansion 
for /F "delims=" %%a in (tmp.txt) do (
    set /A "line[%%a]+=1" 
) 
for /F "tokens=2* delims=[]=" %%a in ('set line[') do (
    echo %%a - %%b 
) 
+0

Я подумал об этом, но любая строка, содержащая [] =, вызовет неожиданные результаты. Так как это предназначено для использования с макросом для Notepad ++, то понятно, что в выбранном тексте он будет проверять дублирующие строки. +1 для больших умов тоже думают. – rojo

+0

Я просто сделал небольшое исправление, которое позволяет любое содержимое в строке, за исключением специальных символов партии, таких как восклицательный знак – Aacini

3

У меня есть другое, но простое решение для Вас.

Вы можете скачать GNU utilities for win32. Затем просто извлеките его. Это набор переносимых инструментов для Windows. Очень удобно.

Затем используйте программы sort и uniq. Вы можете найти их в

extracted_folder\usr\local\wbin\ 

, то вы можете просто сделать

sort original_file.txt | uniq --count > count.txt 

из окон command line. Вы найдете то, что вам нужно в count.txt


Убедитесь, что пути исправить или у вас есть извлеченная папка в path. Если не в пути, то сделайте что-то вроде

"C:\GNUWin_standalone\usr\local\wbin\sort.exe" original_file.txt | "C:\GNUWin_standalone\usr\local\wbin\uniq.exe" --count > count.txt 
+2

+1 Из 6 ответов, опубликованных до сих пор, это самый эффективный и единственный, где это не имеет значения существуют ли какие-либо специальные символы в проверяемом контенте. unixutils и gnuwin32 упрощают создание сценариев Windows. – rojo

+0

+1, я впечатлен тем, что вы признаете, что вы должны использовать утилиту GNU 'sort', а не родную утилиту' sort' Windows. Глупый Windows 'sort' нечувствителен к регистру :-( – dbenham

Смежные вопросы