2

我正在尝试在 Notepad++ 中进行批处理,以计算所选文本中重复行的数量。

到目前为止,我的 Notepad++ 工作正常

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

此脚本将选定的文本保存到tmp.txt其中,唯一的问题是它包含在底部,CON_SAVETO "H:\tmp.txt"但我现在可以忍受。

编辑:另外,我不认为 N​​otepad++ 是这里的问题,因为我尝试从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

所以理想的输出是:

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

6 回答 6

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%

这是我的版本。对输入文件进行排序,将类似的行组合在一起,然后当行内容发生变化时,显示以前的内容并计数并重置上一行的计数器和记录。

于 2013-04-05T19:40:47.000 回答
3

只要行不包含某些特殊的批处理字符,下面的批处理程序就会以更快的方式执行您想要的操作:

@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
)
于 2013-04-05T20:21:59.090 回答
3

我有一个不同但更简单的解决方案给你。

您可以下载用于 win32 的 GNU 实用程序。然后只需提取它。它是 Windows 移植工具的集合。非常便利。

然后从那里使用sortanduniq程序。你可以在...里找到它们

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
于 2013-04-05T20:22:21.437 回答
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循环体移动到子程序中。

于 2013-04-05T19:18:17.790 回答
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]!"
)
于 2013-04-05T19:40:37.923 回答
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!"
)

如果您正确发布内容,您的代码毫无意义tmp.txt

于 2013-04-05T19:22:59.843 回答