批量.txt到.csv转换

时间:2017-01-27 12:11:40

标签: powershell csv batch-file

我需要转换内容如下的txt文件:

IP Address= 10.191.128.236 
 
1.3.6.1.4.1.119.2.3.69.5.1.1.1.3.1 = PX44025A
1.3.6.1.4.1.119.2.3.69.5.1.1.1.6.1 = 10.191.128.236
1.3.6.1.4.1.119.2.3.69.501.7.10.1.3.1 = TRP-80G1000MB-1A
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.3.1 = BB CKT          
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.4.1 = NWA-078320-003  
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.7.1 = 3.10.09
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.8.1 = 3.10.09
1.3.6.1.4.1.119.2.3.69.501.7.2.1.3.1 = EXBB            
1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1 = NWA-078332-001  
1.3.6.1.4.1.119.2.3.69.501.7.2.1.5.1 = 3.51
.............................................
 
IP Address= 10.191.160.169 
 
Request timed out.
.............................................
 
IP Address= 10.191.128.242 
 
1.3.6.1.4.1.119.2.3.69.5.1.1.1.3.1 = PX44025D
1.3.6.1.4.1.119.2.3.69.5.1.1.1.6.1 = 10.191.128.242
1.3.6.1.4.1.119.2.3.69.501.7.10.1.3.1 = TRP-80G1000MB-1A
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.3.1 = BB CKT          
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.4.1 = NWA-078320-003  
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.7.1 = 3.10.09
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.8.1 = 3.10.09
1.3.6.1.4.1.119.2.3.69.501.7.2.1.3.1 = EXBB            
1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1 = NWA-078332-001  
1.3.6.1.4.1.119.2.3.69.501.7.2.1.5.1 = 3.51
.............................................

如果要测试脚本,可以从http://x.x.x.x/Convert/获取示例源文件。 标题应根据" ="之前的项目进行准备。那么" ="之后的信息;以及" ..........."应放在一行(每个IP地址分开一行),如下例所示:

IP Address,1.3.6.1.4.1.119.2.3.69.5.1.1.1.3.1,1.3.6.1.4.1.119.2.3.69.5.1.1.1.6.1,1.3.6.1.4.1.119.2.3.69.501.7.10.1.3.1,1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.3.1, 1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.4.1,1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.7.1,1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.8.1,1.3.6.1.4.1.119.2.3.69.501.7.2.1.3.1,1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1, 1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1,1.3.6.1.4.1.119.2.3.69.501.7.2.1.5.1

10.191.128.236,PX44025A,10.191.128.236,TRP-80G1000MB-1A,BB CKT,NWA-078320-003,3.10.09,3.10.09,EXBB,NWA-078332-001,3.51
10.191.160.169,Request timed out.
10.191.128.242,PX44025D,10.191.128.242,TRP-80G1000MB-1A,BB CKT,NWA-078320-003,3.10.09,3.10.09,EXBB,NWA-078332-001,3.51

当然文件可以包含更多数据,上面只是一个例子。 我尝试使用for / f,令牌,delims等创建我自己的批次,但最终放弃了...... 谁能帮我准备呢?

输出将用于导入Excel(允许过滤文件内容)。

下面看我的辛勤工作":

@echo off
setlocal enabledelayedexpansion
echo IP Address,1.3.6.1.4.1.119.2.3.69.5.1.1.1.3.1,1.3.6.1.4.1.119.2.3.69.5.1.1.1.6.1,1.3.6.1.4.1.119.2.3.69.501.7.10.1.3.1,1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.3.1, 1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.4.1,1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.7.1,1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.8.1,1.3.6.1.4.1.119.2.3.69.501.7.2.1.3.1,1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1, 1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1,1.3.6.1.4.1.119.2.3.69.501.7.2.1.5.1 >out.csv 
for %%i in (Input.txt) do (
  set "x="
  for /f "tokens=2,3,4,5 delims=:=" %%a in (Input.txt) do set x=!x!%%a %%b %%c %%d,
  set x=!x:  =!
  set x=!x:       =!
  set x=!x:~0,-1!
  echo !x!>>out.csv
)

问题是我不知道如何在必要时转移到下一行...... 在此先感谢您的支持!

7 个答案:

答案 0 :(得分:1)

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q41893731.txt"
SET "outfile=%destdir%\outfile.txt"
:: Part one - accumulate unique column1 entries from entire file
SET "colones="
FOR /f "usebackqtokens=1*delims==" %%a IN ("%filename1%") DO IF "%%b" neq "" (
 ECHO "!colones!"|FIND "%%a," >NUL
 IF ERRORLEVEL 1 SET "colones=!colones!,%%a"
)
SET "colones=%colones:~1,-1%"
SET "colones=%colones: ,=,%"
>"%outfile%" ECHO(%colones%
:: Part two - accumulate column2 entries from sections
(
SET "coltwos="
FOR /f "usebackqtokens=*" %%z IN ("%filename1%") DO (
 FOR /f "tokens=1*delims==" %%a IN ("%%z") DO (
  REM Is this an "IP Address" line?
  IF "%%a"=="IP Address" (
   CALL :report
   SET "coltwos=%%b"
   SET "nextline="
   SET "nodata=Y"
  ) ELSE (
   REM save line following "IP Address" line
   IF NOT DEFINED nextline SET "nextline=%%z"
   IF "%%b" neq "" SET "nodata="&SET "coltwos=!coltwos!,%%b"
  )
 )
)
CALL :report
)>>"%outfile%"

GOTO :EOF

:report
IF NOT DEFINED coltwos GOTO :EOF 
SET "coltwos=%coltwos: =%"
IF DEFINED nodata (
 ECHO(%coltwos%,%nextline%
) ELSE (
 ECHO(%coltwos%
)
GOTO :eof

您需要更改sourcedirdestdir的设置以适合您的具体情况。

我使用了一个名为q41893731.txt的文件,其中包含我的测试数据。

生成定义为%outfile%

的文件

Pass1读取包含=的所有行的每个列1条目并累积,忽略重复项。然后删除杂散的前导和尾随字符,并将所有,替换为,

这是假设,因为输出要求不清楚。 501.7.2.1.4.1条目似乎是重复的,并且包含了一个杂散空间。

第二遍使用类似的技术来累积第二列的内容,使用IP Address行的外观来表示某个部分已完成,因此可以报告。

保存IP Address行后面的行,因为如果列表中没有条目,则会简单地再现其内容。

如果找到条目,则清除nodata,表示coltwos已累积报告。如果找不到数据,coltwos + nextline包含所需的报告数据。

请注意,第一次传递创建输出文件(因此>),第二次传递附加到该文件(因此>>

修订

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q41893731.txt"
SET "outfile=%destdir%\outfile.txt"
:: Part one - accumulate unique column1 entries from entire file
SET "colones="
FOR /f "usebackqtokens=1*delims==" %%a IN ("%filename1%") DO IF "%%b" neq "" (
 ECHO "!colones!,"|FIND "%%a," >NUL
 IF ERRORLEVEL 1 SET "colones=!colones!,%%a"
)
SET "colones=%colones:~1,-1%"
SET "colones=%colones: ,=,%"
>"%outfile%" ECHO(%colones%
:: Part two - accumulate column2 entries from sections
(
SET "coltwos="
FOR /f "usebackqtokens=*" %%z IN ("%filename1%") DO (
 FOR /f "tokens=1*delims==" %%a IN ("%%z") DO (
  REM Is this an "IP Address" line?
  IF "%%a"=="IP Address" (
   CALL :report
   SET "coltwos=%%b"
   SET "nextline="
   SET "nodata=Y"
  ) ELSE (
   REM save line following "IP Address" line
   IF NOT DEFINED nextline SET "nextline=%%z"
   IF "%%b" neq "" SET "nodata="&SET "coltwos=!coltwos!,%%b"
  )
 )
)
CALL :report
)>>"%outfile%"

GOTO :EOF

:report
IF NOT DEFINED coltwos GOTO :EOF 
SET "coltwos=%coltwos: ,=,%"
if "%coltwos%" neq "%coltwos: ,=%" GOTO report
SET "coltwos=%coltwos:, =,%"
if "%coltwos%" neq "%coltwos:, =%" GOTO report
IF DEFINED nodata (
 ECHO(%coltwos:~1%,%nextline%
) ELSE (
 ECHO(%coltwos:~1%
)
GOTO :eof

鉴于dbenham的批评,通过将,附加到colones find的值来解决标题数据的重复问题,以便colones出现包括逗号。

通过调整:report例程中删除空格的方式,通过更改每个空格 - 逗号对,可以解决缺失空间问题使用单个逗号直到不再存在,然后通过echo

中的子字符串删除前导空格

答案 1 :(得分:0)

您应始终描述问题的规范,而不只是展示示例。下面的批处理文件解决方案创建您请求的相同输出,但如果实际数据的格式与示例数据不同,则此程序将失败...

@echo off
setlocal EnableDelayedExpansion

set "delim=............................................."
call :procFile > out.csv
goto :EOF


:procFile

rem Create the header
< NUL (
set /P "=IP Address"
for /F "skip=1" %%a in (input.txt) do (
   if "%%a" equ "%delim%" goto endHeader
   set /P "=,%%a"
))
:endHeader
echo/

rem Create the rest of data
set "data="
< NUL (
for /F "tokens=1,2 delims==" %%a in (input.txt) do (
   if "%%a" equ "%delim%" (
      echo !data:~1!
      set "data="
   ) else (
      if defined data set /P "=!data:~1!," & set "data="
      if "%%b" neq "" (
         set "data=%%b"
      ) else (
         if "%%a" neq " " set "data= %%a"
      )
   )
))
exit /B

答案 2 :(得分:0)

下面的解决方案不会假设每个部分的行数或行数。即使订单不同,或者某些IP缺失值,它们也能正常工作。该脚本还会从所有值中删除前导和尾随空格。

对于性能测试,我使用3660个IP地址将OP的样本数据复制到~1.6 MB。

只要标题符合批量8kb可变大小限制,这是一个快速而强大的解决方案。 1.6 MB文件需要24秒才能处理。

@echo off
setlocal enableDelayedExpansion

set "input=test.txt"
set "output=fast.csv"

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

for /f "delims== " %%N in ('findstr "^[0-9][0-9]*\." "%input%"') do set "$%%N=1"
set "header="
for /f "delims=$=" %%N in ('set $') do set "header=!header!,%%N"

>"%output%" (
  echo IP Address!header!
  for /f "usebackq tokens=1* delims== " %%A in ("%input%") do (
    if "%%A" equ "IP" (
      set "ip=%%~nxB"
      for %%V in (!header!) do set "$%%V="
    ) else if "%%A" equ "Request" (
      echo !ip:* =!,Request timed out.
      set "ip="
    ) else if "%%B" equ "" (
      if "%%A" equ "............................................." if defined ip (
        set "ln=!ip:* =!"
        for %%V in (!header!) do set "ln=!ln!,!$%%V!"
        echo !ln!
        set "ip="
      )
    ) else set "$%%A=%%~nxB"
  )
)

这是一个应该始终有效的慢速解决方案,无论标头大小如何。此版本需要98秒来处理1.6 MB文件。

@echo off
setlocal enableDelayedExpansion

set "input=test.txt"
set "output=slow.csv"

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

for /f "delims== " %%N in ('findstr "^[0-9][0-9]*\." "%input%"') do set "$%%N=1"

<nul >"%output%" (
  set /p "=IP Address"
  for /f "delims=$=" %%N in ('set $') do set /p "=,%%N"
  echo(
  for /f "usebackq tokens=1* delims== " %%A in ("%input%") do (
    if "%%A" equ "IP" (
      set "ip=%%~nxB"
      for /f "delims=$=" %%N in ('set $') do set "_%%N="
    ) else if "%%A" equ "Request" (
      echo !ip:* =!,Request timed out.
      set "ip="
    ) else if "%%B" equ "" (
      if "%%A" equ "............................................." if defined ip (
        set /p "=!ip:* =!"
        for /f "delims=$=" %%N in ('set $') do set /p "=,!_%%N!"
        echo(
        set "ip="
      )
    ) else set "_%%A=%%~nxB"
  )
)

编辑以下是具有广泛评论的快速代码

@echo off
setlocal enableDelayedExpansion

set "input=%~1"
set "output=fast.csv"

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

:: Scan entire file for a list of unique header entries
:: only look at lines that begin number followed by a dot.
:: For each found value, define a variable named ${address}, with a value of 1
for /f "delims== " %%N in ('findstr "^[0-9][0-9]*\." "%input%"') do set "$%%N=1"

:: Build a comma delimited list of addresses for the header
:: by scanning all the $ variables
set "header="
for /f "delims=$=" %%N in ('set $') do set "header=!header!,%%N"

:: Enclose remaining code in parens and redirect once for better speed.
>"%output%" (

  %= Print out the header line =%
  echo IP Address!header!

  %= Parse all lines of file into two tokens, delimited by = and/or space =%
  %= 1* means the 2nd token can include delimiters                        =%
  for /f "usebackq tokens=1* delims== " %%A in ("%input%") do (

    if "%%A" equ "IP" (
      %= IP Address line =%
      set "ip=%%~nxB"                         %= Save the IP Address   =%
      for %%V in (!header!) do set "$%%V="    %= Clear all $ variables =%

    ) else if "%%A" equ "Request" (
      %= Request timed out. line =%
      (echo !ip:* =!,Request timed out.) %= Write out the "timed out" line =%
      set "ip="                          %= Clear ip so no other output for this section =%

    ) else if "%%B" equ "" (  %= Only one token =%
      if "%%A" equ "............................................." if defined ip (
        %= Only process if end of IP Address and ip is still defined =%

        set "ln=!ip:* =!"  %= Initialize line as IP Address =%
                           %= Remove all leading text up through the first space =%

        %= Append the value of each $variable to line, with leading comma =%
        %= Order of values is guaranteed to match header =%
        for %%V in (!header!) do set "ln=!ln!,!$%%V!"

        (echo !ln!)      %= Write the data line =%
        set "ip="        %= Clear ip so no more output until next IP Address =%
      )

    ) else set "$%%A=%%~nxB"   %= Main data line - Save value in $ variable         =%
                               %= ~nx treats the value as a file name and extension =%
                               %= so trailing space(s) are removed                  =%
  )
)

JREPL.BAT解决方案非常快

为了好玩,我决定使用JREPL.BAT实现一个解决方案 - 一个正则表达式命令行文本处理器,编写为混合批处理/ JScript。与我的纯批处理解决方案不同,此JREPL解决方案假定所有IP地址具有相同数量的数据行,具有相同的地址。这不是那么强大,但它是大多数其他人在答案中所假设的。

使用JREPL.BAT,我将input1.txt的处理时间从4.5秒减少到0.8秒。但大部分时间都花在初始化JScript上。随着输入文件大小的增加,JREPL的性能真正开始闪耀。例如,我的&#34;快速&#34; 1.6 MB测试文件需要24秒。纯批量解决方案,我的JREPL解决方案只用了2秒钟!

@echo off
setlocal

set "input=test.txt"
set "output=jrepl.csv"

:: Compute and write header
call jrepl "^\d[\d.]+"^
           "head+=','+$0;$txt=false"^
           /inc "/^\d+\.//:/^\.+/"^
           /jbeg "var head='IP Address'"^
           /jend "output.WriteLine(head)"^
           /jmatchq /f "%input%" /o "%output%"

:: Compute and append data
call jrepl "^IP Address\s*=\s*([\d.]+)@^Request timed out\.@^[\d.]+\s*=\s*(.*?)\s*$@^[.]+"^
           "x=$2;$txt=false;@x+=','+$0;$txt=false;@x+=','+$5;$txt=false;@$txt=x"^
           /t @ /jmatchq /jbeg "var x" /f "%input%" >>"%output%"

答案 3 :(得分:0)

这是另一个纯解决方案,它不依赖于文件中的任何特定文本,它识别由句点.和等号=组成的分隔线,将每个行的标题与数据分开;如果未找到=,则该行为空(或仅包含 SPACE ),所述分隔符行(.)或错误消息(如{{1你的样本数据)。

文件由for /F loop读取一次,标题在读取第一个块时构建,并且在已经完成时不会一次又一次地重建。如果第一个块无效或不完整,那么不能收集头数据,稍后再完成,然后将头写入临时文件,因为已经有数据写入输出文件;然后将标题与数据结合起来。

您的示例数据包含许多尾随 SPACE ,因此该脚本最多可删除其中的15个。

以下是代码(另请参阅众多解释性Request timed out.评论):

rem

答案 4 :(得分:0)

此答案的目的有两个方面:

  • 展示PowerShell的强大功能和灵活性,它可以提供一个功能强大,相当简洁易读的解决方案,并且运行良好。

  • 显示如何从cmd.exe (常规命令提示符)调用基于PowerShell脚本的解决方案,以及如何借助包装批处理简化此过程文件

如果您在底部发布了 PowerShell代码创建文件Transform.ps1,则可以从cmd.exe(常规命令提示符)按如下方式调用它,以获得所需的内容输出:

powershell -ExecutionPolicy Unrestricted -NoProfile -File .\Transform.ps1 input.txt out.csv

* 谨慎使用-ExecutionPolicy Unrestriced :仅将其与您信任的脚本一起使用 - 请参阅Get-Help about_Execution_Policies
*要使用默认字符编码以外的字符编码,您可以使用-Encoding参数 - 请参阅下文 * -NoProfile跳过加载PowerShell配置文件(用于交互式使用的初始化命令)。

如果使用下面发布的内容创建包装器批处理脚本 Transform.cmd并将其放在与PowerShell脚本相同的目录中,则可以将调用简化为:

Transform input.txt out.csv

包装批处理文件Transform.cmd的内容:

@powershell.exe -ExecutionPolicy Unrestricted -NoProfile -File "%~dpn0.ps1" %*

只要批处理文件的文件名根目录和PowerShell脚本相同,就像在Transform.cmdTransform.ps1

中一样,此包装器通常可以正常工作

PowerShell脚本Transform.ps1的内容:

  • 兼容性:代码使用PowerShell v3 +功能,但也可以与PSv2配合使用。

  • 字符编码:默认情况下,使用PowerShell的Default编码,这是您系统隐含的单字节扩展ASCII编码&#39 ;遗留的Windows代码页设置。

    • 您可以通过传递-Encoding <encoding>来更改编码以匹配您的输入文件,但请注意输出文件将始终使用相同的编码(尽管这很容易更改)。
    • 接受的编码名称为Unicode, BigEndianUnicode, UTF8, UTF7, UTF32, Ascii, Default, Oem, BigEndianUTF32(请参阅-Encoding参数说明here),但请注意,Excel无法识别其中一些CSV文件,特别是Unicode 1}}(UTF-16LE)
  • 性能:处理问题中链接的每个示例文件在我2011年末的MacBook Air上花费的时间不到2秒,因此,除非文件大得多,否则性能可能会被接受

  • 评论:代码在较高级别进行了评论,这有望成为进一步探索的起点。

# Declare the script's parameters.
[CmdletBinding(PositionalBinding=$false)]
param(
  [Parameter(Mandatory, Position=1)] [string] $InPath,
  [Parameter(Mandatory, Position=2)] [string] $OutPath,
  [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding] $Encoding = 'Default'
)

# We anticipate no errors, so let's treat even non-terminating ones as 
# terminating.
$ErrorActionPreference = 'Stop'

# The line that separates records.
$recSeparator = '.............................................'

# Get the first record as a single string, so we can later extract the
# CSV column headers from it.
Write-Verbose "Parsing first record to determine header names..."
$firstRec = Get-Content $InPath -Delimiter $recSeparator -Encoding $Encoding |  
  Select-Object -First 1

# Split the first record into an array of lines that contain "="
$firstRecLines = ($firstRec -split '\r?\n') -match '='

# Synthesize the CSV header line from the array of header names obtained from
# the LHS of the "=" on each line.
$colHeaderList = ($firstRecLines -replace '^([^=]+).*', '$1').Trim() -join ','

# Write the header line plus a blank line to the output file.
# The output encoding.
Write-Verbose "Writing header names to '${OutPath}' using encoding '${Encoding}'.."
$colHeaderList + [Environment]::NewLine | Set-Content $OutPath -Encoding $Encoding

# Now process all records and add a line of data fields (only) for each.
Write-Verbose "Processing all records and appending data rows..."
Get-Content $InPath -Delimiter $recSeparator -Encoding $Encoding | ForEach-Object {
  # Split the record at hand into an array of lines...
  $lines = $_ -split '\r?\n'
  # ... and extract the values (the RHS of "=") as an array.
  $values = $lines -match '=' -replace '^.*= (.*)', '$1'
  # Process the values based on how many were found in the record.
  switch ($values.count) {
    0 { return } # Assumed to be the empty record at the end -> ignore
    1 { # Only 1 value? -> must be a "request timed out" record.
      $valuesList = $values[0].Trim() + ',' + $lines[-2]
      break
    } 
    default { # regular data record
      # Join the trimmed values with ',' to form a CSV data line.
      $valuesList = ($values).Trim() -join ','
    }
  }
  # Append the data line to the output file.
  # The output encoding.
  Add-Content -Value $valuesList $OutPath -Encoding $Encoding
}

Write-Verbose "Processing to output file '${OutPath}' completed successfully"

答案 5 :(得分:0)

  1. 读取文件并删除一些空行/特定换行符。
  2. 删除&#34;请求超时&#34;以后的行,因为它们打破了阻止模式。
  3. 正则表达式将块按摩到PowerShell哈希表/对象形状。
  4. eval将它们转换为实时对象,然后将其转换为CSV格式。
  5. 添加&#34;请求超时&#34;行到CSV的末尾。
  6. 它的正则表达式很重且不可读,问题得到了回答和接受,所以为什么不对它进行编码呢。
  7. ~339个字符:

    $T,$B=(((gc -raw Input2.txt)-replace"(?m)^\s*`r`n"-replace
    "(?i)\s*`r`n(?=R)",", ")-split"`r`n").where({$_-match'timed out'},'split')
    ((($B-join"`r`n")-replace"(?m)^(.+?)\s*=\s*(.+?)\s+$","'`$1'='`$2';"-replace
    "(?m)^\.[.`r`n]+","},"-replace"'IP","[PSCustomObject]@{'IP").TrimEnd(",")|
    iex|ConvertTo-Csv -N)+@($T-replace'^.*= ')|sc out.csv
    

    示例输出:

    "IP Address","1.3.6.1.4.1.119.2.3.69.5.1.1.1.3.1","1.3.6.1.4.1.119.2.3.69.5.1.1.1.6.1","1.3.6.1.4.1.119.2.3.69.501.7.10.1.3.1","1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.3.1","1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.4.1","1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.7.1","1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.8.1"
    "10.192.6.199","PI13217A","10.192.6.199","MDP-400MB-1AA","MC-A4","NWA-055298-101","3.00.37","3.00.37"
    "10.192.28.73","PI11747A","10.192.28.73","MDP-400MB-1AA","MC-A4","NWA-055298-101","3.00.37","3.00.37"
    "10.192.28.74","PI12844A","10.192.28.74","MDP-400MB-1AA","MC-A4","NWA-055298-101","3.00.37","3.00.37"
    "10.192.28.75","PI12604A","10.192.28.75","MDP-400MB-1AA","MC-A4","NWA-055298-101","3.02.20","3.02.20"
    "10.192.28.78","PI14189A","10.192.28.78","MDP-400MB-1AA","MC-A4","NWA-055298-101","3.00.37","3.00.37"
    10.192.15.137, Request timed out.
    10.192.16.144, Request timed out.
    10.192.136.201, Request timed out.
    10.192.1.199, Request timed out.
    10.192.153.132, Request timed out.
    

    (是的,最后一行不是以相同的方式引用,但是Excel 2013会处理它)

答案 6 :(得分:-1)

您请求的输出无效CSV。所有行都需要具有相同数量的列。有错误的行没有这个并且将错误放在随机属性中不是一个好的解决方案。我建议添加status列来解决此问题。我不熟悉高级批处理脚本,所以这是使用PowerShell的一个例子:

#Sample data
$str = @"
IP Address= 10.191.160.169 
 
Request timed out.
.............................................
 
IP Address= 10.191.128.236 
 
1.3.6.1.4.1.119.2.3.69.5.1.1.1.3.1 = PX44025A
1.3.6.1.4.1.119.2.3.69.5.1.1.1.6.1 = 10.191.128.236
1.3.6.1.4.1.119.2.3.69.501.7.10.1.3.1 = TRP-80G1000MB-1A
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.3.1 = BB CKT          
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.4.1 = NWA-078320-003  
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.7.1 = 3.10.09
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.8.1 = 3.10.09
1.3.6.1.4.1.119.2.3.69.501.7.2.1.3.1 = EXBB            
1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1 = NWA-078332-001  
1.3.6.1.4.1.119.2.3.69.501.7.2.1.5.1 = 3.51
.............................................
 
IP Address= 10.191.128.242 
 
1.3.6.1.4.1.119.2.3.69.5.1.1.1.3.1 = PX44025D
1.3.6.1.4.1.119.2.3.69.5.1.1.1.6.1 = 10.191.128.242
1.3.6.1.4.1.119.2.3.69.501.7.10.1.3.1 = TRP-80G1000MB-1A
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.3.1 = BB CKT          
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.4.1 = NWA-078320-003  
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.7.1 = 3.10.09
1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.8.1 = 3.10.09
1.3.6.1.4.1.119.2.3.69.501.7.2.1.3.1 = EXBB            
1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1 = NWA-078332-001  
1.3.6.1.4.1.119.2.3.69.501.7.2.1.5.1 = 3.51
.............................................
"@

#Read from file as single string (uncomment to use)
#$str = Get-Content -Path C:\File.txt -Raw

#Pattern to match every "IP address <everything until> ............" to split the Devices in the input
$pattern = "(?ms)ip address=\s+(.+?)\s+?$.+?\s+(.+?)(?=\.{10,})"

$devices = Select-String -InputObject $str -Pattern $pattern -AllMatches | Select-Object -ExpandProperty Matches | ForEach-Object {
    #Foreach device
    $obj = New-Object psobject -Property @{
        "IP" = $_.Groups[1].Value
        "Status" = "OK"
    }

    #Get values
    $valuearray = $_.Groups[2].Value.Split("`r`n",[StringSplitOptions]::RemoveEmptyEntries)

    #If more than one line = status ok, convert data
    #If not, skip to else and update status.
    if($valuearray.Count -gt 1) {
        $valuearray| ForEach-Object {
            #Add values
            $name,$val = $_.Trim() -split ' = '
            Add-Member -InputObject $obj -MemberType NoteProperty -Name $name -Value $val
        }

    } else {
        $obj.Status = $valuearray[0]
    }

    #Output device
    $obj
}

#Get all unique properties (if first object has only IP and Status, every other would be exported with only those without this fix)
$PropertyList = $devices | ForEach-Object { $_.psobject.Properties | ForEach-Object { $_.Name } } | Select-Object -Unique 

$devices | Select-Object -Property $PropertyList | Export-Csv -NoTypeInformation -Patch "C:\out.csv"

输出:

"IP","Status","1.3.6.1.4.1.119.2.3.69.5.1.1.1.3.1","1.3.6.1.4.1.119.2.3.69.5.1.1.1.6.1","1.3.6.1.4.1.119.2.3.69.501.7.10.1.3.1","1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.3.1","1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.4.1","1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.7.1","1.3.6.1.4.1.119.2.3.69.501.7.1.1.1.8.1","1.3.6.1.4.1.119.2.3.69.501.7.2.1.3.1","1.3.6.1.4.1.119.2.3.69.501.7.2.1.4.1","1.3.6.1.4.1.119.2.3.69.501.7.2.1.5.1"
"10.191.160.169","Request timed out.",,,,,,,,,,
"10.191.128.236","OK","PX44025A","10.191.128.236","TRP-80G1000MB-1A","BB CKT","NWA-078320-003","3.10.09","3.10.09","EXBB","NWA-078332-001","3.51"
"10.191.128.242","OK","PX44025D","10.191.128.242","TRP-80G1000MB-1A","BB CKT","NWA-078320-003","3.10.09","3.10.09","EXBB","NWA-078332-001","3.51"