我正在尝试在Notepad ++中进行批处理,它将计算所选文本中重复行的数量。
到目前为止,我的Notepad ++工作正常
NPE_CONSOLE v+
CLS
ECHO $(CURRENT_WORD)
CON_SAVETO "H:\tmp.txt"
NPE_CONSOLE v-
此脚本会将所选文本保存到tmp.txt
,唯一的问题是它包含在底部CON_SAVETO "H:\tmp.txt"
,但我现在可以接受它。
编辑:此外,我认为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
理想的输出是:
1 - 2
2 - 1
3 - 2
4 - 5
5 - 3
6 - 1
7 - 1
8 - 2
答案 0 :(得分: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%
这是我的版本。将输入文件排序为一起分组,然后当行内容更改时,显示先前的内容并计数并重置计数器和上一行的记录。
答案 1 :(得分: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
)
答案 2 :(得分:3)
我有一个不同但更简单的解决方案。
您可以下载GNU utilities for win32。然后提取它。它是Windows的移植工具集合。非常方便。
然后使用那里的sort
和uniq
程序。您可以在
extracted_folder\usr\local\wbin\
然后你可以简单地做
sort original_file.txt | uniq --count > count.txt
来自Windows 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
答案 3 :(得分: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
循环的主体移动到子程序中。
答案 4 :(得分: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]!"
)
答案 5 :(得分: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
的内容,那么你的代码是没有意义的。