-1

我有两个文本文件,我想使用它们来获取 output.txt,如下所示:

文件 1.txt:

Windows                  1.36
Linux                    2.78
MacOS                    3.45
Ubuntu                   4.12
FreePhysicalMemory      30.12
TotalVisibleMemorySize  48.00
CPULoadPercentage         2 

文件2.txt:

MacOS                    6.39
Windows                  4.42
Linux                    5.76
Android                  3.46
FreePhysicalMemory      31.65
TotalVisibleMemorySize  48.00
CPULoadPercentage         4 

输出.txt:

OPERATINGSYSTEM       SERVER1    SERVER2
Windows                  1.36       4.42
Linux                    2.78       5.76
MacOS                    3.45       6.39
Ubuntu                   4.12       0.00
Android                  0.00       3.46
FreePhysicalMemory      30.12      31.65
TotalVisibleMemorySize  48.00      48.00
CPULoadPercentage         2          4

但这里的问题是,使用以下代码我得到了 output.txt 如下所示,其中FreePhysicalMemory 被放错了位置..:

代码:

@echo off
setlocal EnableDelayedExpansion
set i=0
for /F "tokens=1,2" %%a in (file1.txt) do (
   set /A i+=1
   set order[!i!]=%%a
   set info[%%a]=%%b
)

set total2=!order[%i%]!
set /A i-=1
set total1=!order[%i%]!
set /A i-=1

for /F "tokens=1,2" %%a in (file2.txt) do (
   if defined info[%%a] (
      set info[%%a]=!info[%%a]! %%b
   ) else (
      set /A i+=1
      set order[!i!]=%%a
      set info[%%a]=0.00 %%b
   )
)

set /A i+=1
set order[%i%]=%total1%
set /A i+=1
set order[%i%]=%total2%

(
echo OPERATINGSYSTEM       SERVER1    SERVER2
for /L %%i in (1,1,%i%) do (
   for /F %%a in ("!order[%%i]!") do (
      for /F "tokens=1,2" %%b in ("!info[%%a]!") do (
         set "os=%%a                      "
         set "s1=  %%b"
         if "%%c" equ "" (
            set "s2=     0.00"
         ) else (
            set "s2=     %%c"
         )
         echo !os:~0,22!  !s1:~-5!  !s2:~-9!
      )
   )
)
) > output.txt

输出.txt:

OPERATINGSYSTEM       SERVER1    SERVER2
Windows                  1.36       4.42
Linux                    2.78       5.76
MacOS                    3.45       6.39
Ubuntu                   4.12       0.00
FreePhysicalMemory      30.12      31.65
Android                  0.00       3.46
TotalVisibleMemorySize  48.00      48.00
CPULoadPercentage         2          4
4

3 回答 3

2

当然,这是因为您的原始请求两行 totals,而您的新请求有三行

您必须修改程序以包含多行总计:

@echo off
setlocal EnableDelayedExpansion

rem Read info from file1
set i=0
for /F "tokens=1,2" %%a in (file1.txt) do (
   set /A i+=1
   set order[!i!]=%%a
   set info[%%a]=%%b
)

rem Save totals
set total3=!order[%i%]!
set /A i-=1
set total2=!order[%i%]!
set /A i-=1
set total1=!order[%i%]!
set /A i-=1

rem Read/merge info from file2
for /F "tokens=1,2" %%a in (file2.txt) do (
   if defined info[%%a] (
      set info[%%a]=!info[%%a]! %%b
   ) else (
      set /A i+=1
      set order[!i!]=%%a
      set info[%%a]=0.00 %%b
   )
)

rem Return totals to end
set /A i+=1
set order[%i%]=%total1%
set /A i+=1
set order[%i%]=%total2%
set /A i+=1
set order[%i%]=%total3%

rem Format and output information
(
echo OPERATING SYSTEM       SERVER1    SERVER2
for /L %%i in (1,1,%i%) do (
   for /F %%a in ("!order[%%i]!") do (
      for /F "tokens=1,2" %%b in ("!info[%%a]!") do (
         set "os=%%a                      "
         set "s1=  %%b"
         if "%%c" equ "" (
            set "s2=     0.00"
         ) else (
            set "s2=     %%c"
         )
         echo !os:~0,22!  !s1:~-5!  !s2:~-9!
      )
   )
)
) > output.txt
于 2013-11-02T07:25:57.180 回答
2
@ECHO OFF
SETLOCAL
SET spaces=                                                         x
SET "line="
FOR /f "delims==" %%a IN ('set list 2^>nul') DO SET "%%a="
FOR /f "tokens=1,2" %%a IN (file1.txt) DO SET list_%%a=%%b
FOR /f "tokens=1,2" %%a IN (file2.txt) DO (
  IF defined list_%%a (CALL SET list_%%a=%%list_%%a%% %%b
   ) ELSE (SET list_%%a=0.00 %%b
  )
)
FOR /f %%v IN (list.seq) DO IF NOT defined list_%%v SET list_%%v=0.00 0.00
FOR /f "tokens=1,2,3delims== " %%a IN ('set list 2^>nul') DO IF "%%c"=="" SET %%a=%%b 0.00
(
 CALL :show L 22 "OPERATING SYSTEM" L 9 "SERVER1" L 12 "SERVER2"
 FOR /f %%v IN (list.seq) DO (
  FOR /f "tokens=2,3,4delims==_ " %%a IN ('set list_%%v') DO SET "suppdec="&CALL :show L 22 %%a R 7 %%b R 9 %%c&SET "list_%%v="
  )
 FOR /f "tokens=2,3,4delims==_ " %%a IN ('set list_ 2^nul') DO SET "suppdec="&CALL :show L 22 %%a R 7 %%b R 9 %%c
)>output.txt
TYPE output.txt

GOTO :EOF

:show
IF "%~3"=="" GOTO output
IF %1==L (SET column=%~3%spaces%) ELSE (SET column=%spaces:~0,-1%%~3%suppdec%)
IF %1==L (CALL SET line=%%line%%%%column:~0,%2%%) ELSE (CALL SET line=%%line%%%%column:~-%2%%)
SHIFT&shift&SHIFT
ECHO "%~3"|FIND "." >nul
IF ERRORLEVEL 1 (SET "suppdec=  ") ELSE (SET "suppdec=")
GOTO show

:output
ECHO %line%
SET "line="
GOTO :eof

其中list.seq包含

Windows
Linux
Absent
MacOS
Ubuntu
Android
FreePhysicalMemory
TotalVisibleMemorySize
CPULoadPercentage

如果在一个文件中找到了一个元素,但在另一个文件中没有找到,0.00则会出现缺失数据。

如果一个值不包含小数,它将移动 2 个空格以将单位列与小数对齐。

未出现在数据文件中但在文件中提到的元素list.seq将以 0.00 的值出现

出现在数据文件中但未在list.seq文件中提及的元素将按字母顺序出现在 DO 出现的元素之后list.seq

于 2013-11-02T08:04:22.490 回答
2

这是一种完全不同的方法,具有以下功能:

  • 服务器(文件)的数量很容易扩展。只需将一个新文件添加到加载数据部分的外部循环中的列表中。
  • 每个服务器的标头是通过删除扩展名从文件名派生的。
  • 每个服务器列的宽度很容易配置
  • 操作系统标签列的宽度很容易配置
  • 缺失值显示为空白而不是误导性的 0
  • 操作系统标签按字母顺序显示,然后是摘要行。
  • 最后的摘要行的数量和顺序很容易配置。lookup只需在变量中添加或减去值。

我将 FILE1.TXT、FILE2.TXT 重命名为 SERVER1.TXT、SERVER2.TXT。我还将 SERVER1.TXT 复制到 SERVER3.TXT,这样我就可以测试上一列中缺少的值。

@echo off
setlocal enableDelayedExpansion

:: Clear any existing $ variables
for /f "delims==" %%A in ('"set $ 2>nul"') do set "%%A="

:: Load data
set "cnt=0"
set "blank=                                               "
set "width=8"
set "labelWidth=22"
set "lookup= FreePhysicalMemory:2 TotalVisibleMemorySize:3 CPULoadPercentage:4"
for %%F in (server1.txt server2.txt server3.txt) do (
  set "val=%blank%%%~nF"
  set "$0.OPERATINGSYSTEM=!$0.OPERATINGSYSTEM! !val:~-%width%!"
  for /f "tokens=1,2" %%A in (%%F) do (
    set "test=!lookup:* %%A:=!"
    if "!test!" equ "!lookup!" (set "prefix=$1.") else set "prefix=$!test:~0,1!."
    for %%P in (!prefix!) do (
      if not defined !prefix!%%A (
        for /l %%N in (1 1 !cnt!) do set "%%P%%A=!%%P%%A! !blank:~-%width%!"
      ) else if "!%%A!" neq "!cnt!" (
        set "%%P%%A=!%%P%%A! !blank:~-%width%!"
      )
      set "val=%blank%%%B"
      set "%%P%%A=!%%P%%A! !val:~-%width%!"
    )
    set /a "%%A=cnt+1"
  )
  set /a cnt+=1
)

:: Print results
for /f "tokens=2* delims=.=" %%A in ('set $') do (
  set "label=%%A%blank%"
  echo !label:~0,%labelWidth%!%%B
)

- 输出 -

OPERATINGSYSTEM         SERVER1  SERVER2  SERVER3
Android                             3.46
Linux                      2.78     5.76     2.78
MacOS                      3.45     6.39     3.45
Ubuntu                     4.12              4.12
Windows                    1.36     4.42     1.36
FreePhysicalMemory        30.12    31.65    30.12
TotalVisibleMemorySize    48.00    48.00    48.00
CPULoadPercentage             2        4        2

编辑以回应 OP 评论

这是一个修改后的版本,它使用 NULL 来表示缺失值并将输出写入文本文件。

@echo off
setlocal enableDelayedExpansion

:: Clear any existing $ variables
for /f "delims==" %%A in ('"set $ 2>nul"') do set "%%A="

:: Load data
set "cnt=0"
set "blank=                                               "
set  "null=                                           NULL"
set "width=8"
set "labelWidth=22"
set "lineWidth=0"
set "lookup= FreePhysicalMemory:2 TotalVisibleMemorySize:3 CPULoadPercentage:4"
for %%F in (server1.txt server2.txt server3.txt) do (
  set "val=%blank%%%~nF"
  set "$0.OPERATINGSYSTEM=!$0.OPERATINGSYSTEM! !val:~-%width%!"
  for /f "tokens=1,2" %%A in (%%F) do (
    set "test=!lookup:* %%A:=!"
    if "!test!" equ "!lookup!" (set "prefix=$1.") else set "prefix=$!test:~0,1!."
    for %%P in (!prefix!) do (
      if not defined !prefix!%%A (
        for /l %%N in (1 1 !cnt!) do set "%%P%%A=!%%P%%A! !null:~-%width%!"
      ) else if "!%%A!" neq "!cnt!" (
        set "%%P%%A=!%%P%%A! !null:~-%width%!"
      )
      set "val=%blank%%%B"
      set "%%P%%A=!%%P%%A! !val:~-%width%!"
    )
    set /a "%%A=cnt+1"
  )
  set /a cnt+=1, lineWidth+=width+1
)

:: Print results
(for /f "tokens=2* delims=.=" %%A in ('set $') do (
  set "line=%%B !null:~-%width%!"
  set "label=%%A%blank%"
  echo !label:~0,%labelWidth%!!line:~0,%lineWidth%!
))>output.txt
于 2013-11-02T14:41:14.090 回答