-1

我这里有一个文件 file1.txt,内容是这样的

013A不可见???:?09C:DB 2-Way Mir N/Grp'd RW 3     
013B 不可见???:? 07A:DB 2-Way Mir N/Grp'd RW 3     
013C 不可见???:? 08B:DB 2-Way Mir N/Grp'd RW 3          
0242 不可见???:? 10D:D3 RAID-5 N/Grp'd (M) RW 43163     
0246 不可见???:?10A:CB RAID-5 N/Grp'd (M) RW 43163     
024E 不可见???:? 09D:D4 RAID-5 N/Grp'd (M) RW 43163     
02A6 不可见???:? 06B:C8 RAID-5 N/Grp'd (M) RW 43163         
09A8 不可见 ???:? 07C:D1 RAID-6 N/Grp'd (M) RW 43163     
09AA 不可见 ???:? 09D:C1 RAID-6 N/Grp'd (M) RW 43163     
09AC 不可见 ???:? 09A:C2 RAID-6 N/Grp'd (M) RW 43163     
09B0 不可见???:? 08B:C0 RAID-6 N/Grp'd (M) RW 43163

我的任务是在上面以粗体显示的列中搜索单词,并获取每个类别最后一列中数字的总和。

在上面的例子中,我有 3 组词

  1. 2-Way Mir
  2. RAID-5
  3. RAID-6

所以我需要总结最后一列。对于2-Way Mir,总和是3+3+3= 9
如何使用批处理文件收集相同的内容?

实际间距:

4

3 回答 3

1

GNU 的代码:

>awk "{a[$6]+=$NF} END {for (x in a) print x,a[x]}" 文件
RAID-5 172652
2路9
RAID-6 172652

Mir 为了2-Way 您的方便,请添加!
在这里下载

于 2013-07-10T20:00:04.103 回答
0
@ECHO OFF
SETLOCAL
FOR %%i IN (mir2 raid5 raid6) DO SET /a %%i=0
FOR /f "delims=" %%i IN (file1.txt) DO CALL :process %%i
ECHO 2-Way Mir : %mir2%
ECHO RAID-5    : %raid5%
ECHO RAID-6    : %raid6%
GOTO :EOF
:process
SET "line=%*"
:loop
SET value=%2
IF DEFINED value shift&GOTO loop
SET line=%line:~38,9%
IF /i "%line%"=="2-way mir" SET /a mir2+=%1
IF /i "%line%"=="RAID-5   " SET /a raid5+=%1
IF /i "%line%"=="RAID-6   " SET /a raid6+=%1
GOTO :EOF

应该为你做这项工作。我假设密钥字符串周围的星号是使这些字符串变粗的失败尝试。我还假设数据是固定列格式。实际上,如果这是真的,可能有一种更简单的方法:

@ECHO OFF
SETLOCAL
FOR %%i IN (mir2 raid5 raid6) DO SET /a %%i=0
FOR /f "delims=" %%i IN (file1.txt) DO CALL :process %%i
ECHO 2-Way Mir : %mir2%
ECHO RAID-5    : %raid5%
ECHO RAID-6    : %raid6%
GOTO :EOF
:process
SET "line=%*"
IF /i "%line:~38,9%"=="2-way mir" SET /a mir2+=%line:~70%
IF /i "%line:~38,9%"=="RAID-5   " SET /a raid5+=%line:~70%
IF /i "%line:~38,9%"=="RAID-6   " SET /a raid6+=%line:~70%
GOTO :EOF 

如果需要,可以进一步简化。请注意,语句中的长度9必须匹配,并且不区分大小写。if/iif


扩展匹配 - 稍微复杂一点,但会自动调整......

@ECHO OFF
SETLOCAL
FOR /f "delims==" %%i IN ('set $ 2^>nul') DO SET "%%i="
SET maps="2-way mir" "RAID-5   "
SET maps=%maps% "RAID-6   "

SET strcnt=0
FOR %%i IN (%maps%) DO CALL :setup %%i
FOR /f "delims=" %%i IN (file1.txt) DO CALL :process %%i
SET mapnbr=1
:ploop
CALL ECHO %%$_%mapnbr%%% : %%$%mapnbr%%%
SET /a mapnbr+=1
IF %mapnbr% leq %strcnt% GOTO ploop
GOTO :EOF
:process
SET "line=%*"
SET mapnbr=%strcnt%
:matchloop
CALL SET match=%%$_%mapnbr%%%
IF /i "%line:~38,9%"==%match% CALL SET /a $%mapnbr%+=%line:~70%&GOTO :eof
SET /a mapnbr-=1
IF %mapnbr% neq 0 GOTO matchloop
GOTO :EOF

:: Set $n=0 & $_n=string-to-match
:setup
SET /a strcnt+=1
SET /a $%strcnt%=0
SET    $_%strcnt%=%1
GOTO :eof

本质上,变量$n包含计数,$_n要在引号中匹配的字符串。只需将更多带引号的 9 字符字符串添加到maps空格或逗号分隔符中。

于 2013-07-10T19:30:33.717 回答
0

如果任何总和超过 2147483647,批处理数学限制使得无法创建合理的纯批处理解决方案。可以编写复杂的例程来批量执行大量计算,但我不认为它们是合理的。

假设所有总和都小于允许的最大值,则以下解决方案有效。

如果您的“单词”不包含空格,这会容易得多。通常,环境变量的名称中可以包含空格。但是 SET /A 选项不支持变量名中的空格。所以需要一组额外的映射变量来将每个唯一的“单词”映射成一个不包含空格的变量名。如果“单词”从不包含空格,则运行总和可以简单地存储在直接从“单词”派生的变量中。

@echo off
setlocal enableDelayedExpansion

:: Define input file
set "file=file1.txt"

:: Clear any existing $ variables and initialize unique "word" count
for /f "delims==" %%V in ('2^>nul set $') do set "%%V="
set "cnt=0"

:: Iteratively read each line in the file
for /f "usebackq delims=" %%A in ("%file%") do (

  %= Extract the correct "word" (%%N) from the line by position =%
  set "ln=%%A"
  for /f "delims=" %%N in ("!ln:~42,13!") do (

    %= If this is a new "word", then setup mapping =%
    if not defined $%%N (
      set /a cnt+=1        %= Increment unique "word" count     =%
      set "$%%N=!cnt!"     %= Map "word" to an "array" position =%
      set "name!cnt!=%%N"  %= Store "word" in name "array"      =%
    )

    %= Extract the value from line by position and add it to =%
    %= the appropriate array element by using the $word map  =%
    set /a "val!$%%N!+=!ln:~71!"
  )
)

:: Iterate the "arrays" and print results
for /l %%N in (1 1 %cnt%) do echo !name%%N!  !val%%N!

注意:上面的代码使用环境变量命名约定来模拟数组。Batch 没有真正的数组。

以下是 file1.txt 中样本数据的结果:

2-Way Mir      9
RAID-5         172652
RAID-6         172652
于 2013-07-10T22:15:22.417 回答