【问题标题】:How to get required output from a bat file to csv file?如何从 bat 文件获取所需的输出到 csv 文件?
【发布时间】:2014-12-24 14:04:23
【问题描述】:

我必须在 MS-Command 提示符下编写一个 .Bat 文件,以从一个包含 100 个日志文件的文件夹中提取 2 个特定字符串“用户名”和“上次登录时间”,每个日志文件都有这 2 个内容。输出必须打印到 csv 文件报告中才能保存在某处。

echo Processing user's last login time. Please wait...
S:
cd log_files

for %G IN (*.txt) do (findstr /i "Username: Log-In" "%G" >> S:\Sourav\GIS_Login_Time.txt)
echo Execution Complete.
echo Output file created in C:\data folder.
pause

输出文件(txt 格式)如下:

*** OS Username:              ADIELA
*** GIS Username:             adiela ( Laura Adie - Horizons, Bullion )
*** Log-In Time:              21/07/2014 06:37:20
*** OS Username:              allanj1
*** GIS Username:             allanj ( Jim Allan - Shared access Lomond House )
*** Log-In Time:              17/12/2014 11:44:22
...

您能否建议如何修改输出(现在进入文本文件)以进入 csv 文件?输出文件必须有 3 列。 1) 操作系统用户名 2) GIS 用户名 3) 登录时间。 如果我能得到一些有价值的建议,我将不胜感激。 提前谢谢你:)

【问题讨论】:

  • 当您可以使用 PowerShell 时,为什么还要使用 shell 脚本(批处理)?

标签: batch-file csv cmd output findstr


【解决方案1】:

我的JREPL.BAT utility 的另一个完美问题 - 一个混合 JScript/批处理脚本,它执行正则表达式搜索和文本替换。 JREPL.BAT 是纯脚本,可​​以在 XP 以后的任何 Windows 机器上本地运行。

假设每个文件都以相同的顺序包含所有三个条目(尽管不一定是连续的),那么这一行将创建“output.csv”。请注意,我使用续行只是为了使代码更易于阅读。

type *.txt 2>&1 | jrepl ^
  "OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)$[\s\S]*?Log-In Time:\s*(.*?)$" ^
  "'\x22'+$1+'\x22,\x22'+$2+'\x22,\x22'+$3+'\x22'" ^
  /m /jmatch /o output.csv

-- 使用您的示例文本输出--

"ADIELA","adiela ( Laura Adie - Horizons, Bullion )","21/07/2014 06:37:20"
"allanj1","allanj ( Jim Allan - Shared access Lomond House )","17/12/2014 11:44:22"


如果您真的只想要 GPS 用户名,没有括号内的信息,那么您不需要引号,因为您的数据不再包含逗号:

type *.txt 2>&1 | jrepl ^
  "OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)\s[\s\S]*?Log-In Time:\s*(.*?)$" ^
  "$1+','+$2+','+$3" ^
  /m /jmatch /o output.csv

-- 输出--

ADIELA,adiela,21/07/2014 06:37:20
allanj1,allanj,17/12/2014 11:44:22


添加列出列名的标题行很容易:

type *.txt 2>&1 | jrepl ^
  "OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)\s[\s\S]*?Log-In Time:\s*(.*?)$" ^
  "$1+','+$2+','+$3" ^
  /jbeg "output.WriteLine('OS Username,GIS Username,Login Time')" ^
  /m /jmatch /o output.csv

-- 输出--

OS Username,GIS Username,Login Time
ADIELA,adiela,21/07/2014 06:37:20
allanj1,allanj,17/12/2014 11:44:22

【讨论】:

    【解决方案2】:

    这是一个很好的。 以下是我的解决方法:

    @ECHO OFF
    SETLOCAL EnableExtensions EnableDelayedExpansion
    
    SET SourceFile="C:\SourceFile.txt"
    SET OutputFile="C:\List.txt"
    
    SET TempFile1="%TEMP%\1.txt"
    SET TempFile2="%TEMP%\2.txt"
    SET TempFile3="%TEMP%\3.txt"
    
    REM Initialize files.
    ECHO Header>%TempFile1%
    ECHO Header>%TempFile2%
    ECHO Header>%TempFile3%
    
    IF EXIST %OutputFile% DEL %OutputFile%
    
    REM Build a list of each value.
    FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "OS" %SourceFile%`) DO ECHO %%B>>%TempFile1%
    FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "GIS" %SourceFile%`) DO ECHO %%B>>%TempFile2%
    FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "Log-In" %SourceFile%`) DO ECHO %%B>>%TempFile3%
    
    REM All temp files should have the same number of entries.
    REM Concatenate them with a comma.
    SET Skip=1
    
    :ProcessLine
    REM Keep going until we find the first empty entry.
    REM This means we reached the end of the list.
    SET "OSUserName="
    SET "GISUserName="
    SET "LogInTime="
    
    REM Only set the first line.
    FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile1%) DO IF "!OSUserName!"=="" SET OSUserName=%%A
    FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile2%) DO IF "!GISUserName!"=="" SET GISUserName=%%A
    FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile3%) DO IF "!LogInTime!"=="" SET LogInTime=%%A
    
    ECHO %OSUserName%
    REM Check for the end of the list.
    IF "%OSUserName%"=="" GOTO Finish
    
    REM Add to the output.
    ECHO %OSUserName%,%GISUserName%,%LogInTime%>>%OutputFile%
    
    REM Increment counter and loop.
    SET /A Skip=%Skip%+1
    GOTO ProcessLine
    
    :Finish
    REM Cleanup.
    IF EXIST %TempFile1% DEL %TempFile1%
    IF EXIST %TempFile2% DEL %TempFile2%
    IF EXIST %TempFile3% DEL %TempFile3%
    
    ENDLOCAL
    

    【讨论】:

      【解决方案3】:

      这会直接从源文件(没有临时文件)构建您的 csv:

      @echo off
      setlocal enabledelayedexpansion
      REM write first line:
      echo OSUser;GISUser;LoginTime >out.csv
      REM for every .txt file:
      for %%i in (*.txt) do (
        REM add the three strings: 
        set "x="
        for /f "tokens=1,* delims=:" %%a in ('findstr "Username Log-In" %%i') do set x=!x!%%b;
        REM delete any "two consecutive spaces":
        set x=!x:  =!
        REM delete TABs ( it's a TAB between : and = ):
        set x=!x:       =!
        REM delete last ; (if it disturbes you):
        set x=!x:~0,-1!
        REM write it to the file:
        echo !x!>>out.csv
      )
      

      【讨论】:

        猜你喜欢
        • 2021-04-09
        • 2013-06-08
        • 2019-11-07
        • 1970-01-01
        • 2018-05-25
        • 2021-12-07
        • 1970-01-01
        • 2023-01-31
        • 2023-03-24
        相关资源
        最近更新 更多