下面的脚本提供了令牌#1字段每次出现的输出,但我还需要添加两个条件。
一个。应提供输出。即。因为我在文件中有数百万条记录
,所以只有它不止一个湾如果有多个字符串.i.e。需要检查行中的关键字段的组合,以检查文件中的重复项。
@ECHO OFF
SETLOCAL enabledelayedexpansion
FOR %%c IN ($ #) DO FOR /f "delims==" %%i IN ('set %%c 2^>nul') DO
"SET %%i="
SET /a count=0
FOR /f "tokens=1delims=|" %%i IN (fscif.txt) DO (
SET /a count+=1
IF DEFINED $%%i (SET "$%%i=!$%%i! & !count!") ELSE (SET "$%%i=!count!")
SET /a #%%i+=1 )
FOR /f "tokens=1*delims=$=" %%i IN ('set $ 2^>nul') DO ( ECHO %%i;!#%%i! times;line no %%j
)
例如: 原始文件(考虑令牌1和3是关键字段)
123 | 12 |杰克
124 | 23 |约翰
123 | 14 |杰克
125 | 15 |萨姆
125 | 66 |萨姆
125 | 66 |萨姆
输出文件:
123 |杰克; 2次; 1号线& 3
125 | Sam; 3次;第4行& 5& 6
答案 0 :(得分:0)
@ECHO OFF
SETLOCAL enabledelayedexpansion
:: Temporary filename
:tloop
SET "temppfx=%temp%\%random%"
IF EXIST "%temppfx%*" GOTO tloop
:: Hold that tempfile name...
ECHO.>"%temppfx%_"
:: a long string of spaces note the end-of-string quote -----here--v
SET "spaces= "
SET /a count=0
(
FOR /f "tokens=1,3 delims=|" %%a IN (fscif.txt) DO (
SET /a count+=1
SET "field1=%%a%spaces%"
SET "field3=%%b%spaces%"
SET "fieldc=%spaces%!count!"
ECHO(!field1:~0,10!!field3:~0,12!^|!fieldc:~-8!^|!count!^|%%a^|%%b
)
)>"%temppfx%1"
:: Now report
SET "key=x"
SET /a count=0
(
FOR /f "tokens=1,3* delims=|" %%a IN ('sort "%temppfx%1" ') DO (
IF "!key!"=="%%a" (
SET "line=!line! %%b"
SET /a count+=1
) ELSE (IF !count! neq 0 CALL :output
SET key=%%a
SET line=%%b
SET "data=%%c"
SET /a count=1
)
)
CALL :output
)>report.txt
del "%temppfx%*"
GOTO :eof
:output
ECHO(!data!;%count% times;line nos %line: = ^& %
GOTO :eof
正如我之前解释的那样,拥有数百万条记录,您可能会耗尽环境空间。如上所述,我认为您可能仍然用完,因为行号的报告可能很大 - 不知道 - 您熟悉您的真实数据。
基本上,首先要做的是建立一个临时文件。
从输入文件中所需的标记开始 - 我跟随1和3,但毫无疑问可能会有更多 - 只需按照弹跳球...
选中的字段将填充 - 在文本字段的右侧,使用spaces
变量在计数字段的左侧。
然后生成tempfile输出。我随机选择第一个字段的最大长度为10,第二个字段的最大长度为12。这两个结合起来给出key
字段。前导填充计数字段作为第二列输出,以便在SORT
之后,数据将按键分组,然后按行号分组。然后再现其余感兴趣的列。
然后将数据作为输入分类到下一个for/f
循环 - 只有令牌1(密钥),3(原始行号)和“其余”(没有填充的密钥)是感兴趣的
然后,只需计算匹配的密钥并在line
中累积行号并在密钥更改时进行报告。报告最后一个数据项需要最后一个输出,我们已经完成了。
答案 1 :(得分:0)
对于这个丑陋的批处理作业,我建议使用GNUWin项目中的sed
和uniq
:
@echo off&setlocal enabledelayedexpansion
set "inputfile=file"
set "outputfile=out"
set "tempfile=%temp%\%random%"
<"%inputfile%" sed "s/|.*|/|.*|/"|sort|uniq -d>"%tempfile%"
(for /f "usebackqtokens=1-3delims=|" %%i in ("%tempfile%") do (
set /a cnt=0&set "line="
for /f "delims=:" %%a in ('findstr /nr "%%i|%%j|%%k" "%inputfile%"') do set "line=!line!%%a & "&set /a cnt+=1
echo(%%i^|%%k;!cnt! times;line no !line:~0,-3!
))>"%outputfile%"
del "%tempfile%"
type "%outputfile%"
..输出是:
123|Jack;2 times;line no 1 & 3 125|Sam;3 times;line no 4 & 5 & 6
答案 2 :(得分:0)
下面的批处理文件可以执行您想要的操作:
@echo off
setlocal EnableDelayedExpansion
rem Assemble "tokensValues" and "lastToken" variables from the parameters
set letters=0abcdefghijklmnopqrstuvwxyz
set tokensValues=%%!letters:~%1,1!
set lastToken=%1
:nextArg
shift
if "%1" equ "" goto endArgs
set "tokensValues=!tokensValues!@%%!letters:~%1,1!"
set lastToken=%1
goto nextArg
:endArgs
rem Accumulate duplicated strings
set line=0
for /F "tokens=1-%lastToken% delims=|" %%a in (fscif.txt) do (
set /A line+=1
if not defined lines[%tokensValues%] (
set lines[%tokensValues%]=!line!
) else (
set "lines[%tokensValues%]=!lines[%tokensValues%]! & !line!"
)
set /A times[%tokensValues%]+=1
)
rem Show the result
for /F "tokens=2* delims=[]=" %%a in ('set lines[ 2^>NUL') do (
if !times[%%a]! gtr 1 (
set string=%%a
set "string=!string:@=|!"
echo !string!;!times[%%a]! times;line no %%b
)
)
您必须在参数中提供所需关键字段的数量。例如,考虑1&amp; 3作为关键字段:
prog.bat 1 3
您最多可以提供26个关键字段,位置从1到26;这个限制可能很容易增加到52。
此批处理文件不使用任何外部命令并对原始文件起作用,因此它应该快速运行。如果文件很大,则sort
或findstr
命令会花费太长时间(即使是简单的copy
)。
如果我们将您的示例数据作为实际数据的代表,lines
变量应该存储大约2500-3000行(即,出现相同关键字段的不同行的数量),以及总环境64 MB的空间我认为这个程序将能够处理你的大文件。