提取文本文件中特定行的值和日期

时间:2018-06-27 13:54:22

标签: batch-file

每周我都会收到6或7个.txt文件,如下所示:

20/06/18 08:18  1   14 (Sucess, no confirmation needed) 00  0   TEST2   ANOTHERS/ADM    2   0   0                       1   164 000000                                  complete operation  44376390                0   1   CLIENT Windows  48                          
20/06/18 08:19  1   1 (ok)  00  1   TEST    ANOTHERS/ADM    2   0   0                       4   167 000000                                  TRANSACAO APROVED   44376393                0   1   CLIENT Windows  48                          
20/06/18 08:21  1   2 (ok)  01  0   TEST2   ANOTHERS/ADM    2   0   0                       4       000000                                  complete operation                  0   0       48                          
20/06/18 08:25  1   14 (Sucess, no confirmation needed) 00  0   TEST2   ANOTHERS/ADM    2   0   0               986     5   168 000000                          41031930        BEGIN OK    44376394                0   1   CLIENT Windows  48                          
20/06/18 08:31  1   14 (Sucess, no confirmation needed) 01  0   TEST2   ANOTHERS/ADM    2   0   0               986     6   129 000000                          41031931        BEGIN OK    51321421                0   1   CLIENT Windows  48                          
20/06/18 08:32  1   14 (Sucess, no confirmation needed) 00  0   TEST2   ANOTHERS/ADM    2   0   0                       6   169 000000                          41031930        BAIXA OK    44376395                0   1   CLIENT Windows  48                          
20/06/18 08:32  1   14 (Sucess, no confirmation needed) 00  0   TEST2   ANOTHERS/ADM    2   0   0                       7   170 000000                          41031930        TEST OK 44376396                0   1   CLIENT Windows  48                          
20/06/18 08:33  1   14 (Sucess, no confirmation needed) 01  0   TEST2   ANOTHERS/ADM    2   0   0                       7   130 000000                          41031931        BAIXA OK    51321422                0   1   CLIENT Windows  48                          
20/06/18 08:33  1   14 (Sucess, no confirmation needed) 01  0   TEST2   ANOTHERS/ADM    2   0   0                       8   131 000000                          41031931        TEST OK 51321423                0   1   CLIENT Windows  48                          
20/06/18 08:38  1   2 (ok)  00  4   TEST3   ANOTHERS/ADM    2   0   0                       11      585945                                  complete operation                  0   0       48                          
20/06/18 08:38  1   2 (ok)  00  4   TEST3   ANOTHERS/ADM    2   0   0                       12      585946                          00000001    000000000001064 SITUACAO DA TEST OK                 0   0       48                          
20/06/18 08:39  1   2 (ok)  01  4   TEST3   ANOTHERS/ADM    2   0   0                       10      585946                                  complete operation                  0   0       48                          
20/06/18 08:39  1   2 (ok)  01  4   TEST3   ANOTHERS/ADM    2   0   0                       11      585947                          00000002    000000000001064 SITUACAO DA TEST OK                 0   0       48                          
20/06/18 09:28  1   1 (ok)  01  0   TEST2   VD DEB  1   2   1   1       FOUND DEBITO    986 11,61   13  134 586242  586242  229873              41031931    0010505962400001    APROVED 229873  12              0   1   CLIENT Windows  48                          
20/06/18 09:40  1   1 (ok)  01  1   TEST    ANOTHERS/ADM    0   0   0                       14  135 000000                                                      0   1   CLIENT Windows  48                          
20/06/18 10:40  1   1 (ok)  01  0   TEST2   VD CRED 3P LOJ  1   1   3   3       FOUND CREDITO   986 154,30  15  136 586244  586244  600109              41031931    0010505962400001    APROVED 600109  19              0   1   CLIENT Windows  48                          
20/06/18 11:32  1   1 (ok)  01  4   TEST3   VD CRED 6P LOJ  1   1   3   6       FOUND   986 369,80  17  138 585948  00184281    009989              00000002    000000000001064 AUTORIZED   21              0   1   CLIENT Windows  48                          
20/06/18 11:56  1   1 (ok)  01  1   TEST    VD CRED 6P LOJ  1   1   3   6       FOUND   986 103,80  18  139 000761  248937832   071579              DK059325    000000046782664 TRANSACAO APROVED   24              0   1   CLIENT Windows  48                          
20/06/18 12:24  1   1 (ok)  01  0   TEST2   VD DEB  1   2   1   1       FOUND DEBITO    986 9,90    19  140 586246  586246  295898              41031931    0010505962400001    APROVED 295898  26              0   1   CLIENT Windows  48                          
20/06/18 13:48  1   1 (ok)  01  4   TEST3   VD CRED 3P LOJ  1   1   3   3       TEST3           986 174,85  23  146 585950  00354147    244207              00000002    000000000001064 AUTORIZED   36              0   1   CLIENT Windows  48                          
20/06/18 13:50  1   1 (ok)  01  4   TEST3   VD DEB 3P LOJ   1   2   3   3       FOUND   986 90,79   24  147 585951  00356608    356608              00000002    000000000001064 AUTORIZED   37              0   1   CLIENT Windows  48                          
20/06/18 14:44  1   1 (ok)  01  4   TEST3   VD CRED 2P LOJ  1   1   3   2       FOUND   986 73,70   26  150 585952  00417993    OCP3EF              00000002    000000000001064 AUTORIZED   42              0   1   CLIENT Windows  48                          
20/06/18 14:55  1   1 (ok)  01  4   TEST3   VD DEB  1   2   1           FOUND   986 30,80   27  151 585953  00432024    432024              00000002    000000000001064 AUTORIZED   44              0   1   CLIENT Windows  48                          
20/06/18 15:11  1   1 (ok)  01  4   TEST3   VD DEB  1   2   1           FOUND   986 56,80   28  152 585954  00451469    451469              00000002    000000000001064 AUTORIZED   48              0   1   CLIENT Windows  48                          
20/06/18 15:16  1   1 (ok)  01  4   TEST3   VD CRED 3P LOJ  1   1   3   3       FOUND   986 473,40  29  153 585955  00458420    051473              00000002    000000000001064 AUTORIZED   49              0   1   CLIENT Windows  48                          
20/06/18 15:21  1   1 (ok)  01  4   TEST3   VD CRED 5P LOJ  1   1   3   5       FOUND   986 89,90   30  154 585956  00464225    210069              00000002    000000000001064 AUTORIZED   52              0   1   CLIENT Windows  48                          
20/06/18 15:22  1   1 (ok)  01  4   TEST3   VD DEB 2P LOJ   1   2   3   2       FOUND   986 74,79   31  155 585957  00466243    466243              00000002    000000000001064 AUTORIZED   53              0   1   CLIENT Windows  48                          
20/06/18 15:25  1   1 (ok)  01  4   TEST3   VD CRED 3P LOJ  1   1   3   3       FOUND   986 51,80   32  156 585958  00469765    R62243              00000002    000000000001064 AUTORIZED   54              0   1   CLIENT Windows  48                          
20/06/18 15:28  1   1 (ok)  01  4   TEST3   VD CRED 2P LOJ  1   1   3   2       FOUND   986 66,80   33  157 585959  00474327    068082              00000002    000000000001064 AUTORIZED   56              0   1   CLIENT Windows  48                          
20/06/18 16:04  1   1 (ok)  01  4   TEST3   VD CRED     1   1   1           FOUND   986 42,60   34  158 585960  00522515    132114              00000002    000000000001064 AUTORIZED   63              0   1   CLIENT Windows  48                          
20/06/18 16:19  1   1 (ok)  01  4   TEST3   VD DEB 2P LOJ   1   2   3   2       FOUND   986 54,50   35  159 585961  00543569    543569              00000002    000000000001064 AUTORIZED   64              0   1   CLIENT Windows  48                          
20/06/18 16:28  1   1 (ok)  01  4   TEST3   VD CRED     1   1   1           FOUND   986 53,60   36  160 585962  00555871    096895              00000002    000000000001064 AUTORIZED   65              0   1   CLIENT Windows  48                          
20/06/18 16:36  1   1 (ok)  01  4   TEST3   VD CRED 2P LOJ  1   1   3   2       TEST3           986 135,40  37  161 585963  00567178    645238              00000002    000000000001064 AUTORIZED   67              0   1   CLIENT Windows  48                          
20/06/18 17:09  1   3 (manually confirmed)  01  4   TEST3   VD CRED 2P LOJ  1   1   3   2       TEST3           986 43,69   41  165 585964  00615982    043774              00000002    000000000001064 AUTORIZED   69              0   1   CLIENT Windows  48                          
20/06/18 17:11  1   1 (ok)  01  4   TEST3   ANOTHERS/ADM    0   0   0                       42  166 000000                                  complete operation                  0   1   CLIENT Windows  48                          
20/06/18 17:47  1   1 (ok)  01  4   TEST3   VD DEB  1   2   0           TEST3           986 48,80   43  167 585965  00682484    164024              00000002    000000000001064 AUTORIZED   73              0   1   CLIENT Windows  48                          
36  AA295617939D4C16073C5AD86919821D101770A4    221163  0

它们的行数不同,日期也不同,值也不同。

但是我需要的很简单,我只需要.bat中的脚本来找到.txt文件(36 AA295617939D4C16073C5AD86919821D101770A4 221163 0)的最后一行并取第三列的值{ {1}},然后将其转换为USD:221163。然后,以上述USD 2.211,63行中第一列的日期为准,并与该值连接。 必须像这样:20/06/18

好,所以现在它将像20/06/18 USD 2.211,63一样保存。 它必须对文件夹中的所有all_files.txt文件进行处理,并保存在相同的输出文件中。结果将像这样:

.txt

我通过这种方式进行尝试:

20/06/18  USD 2.211,63
24/06/18  USD 8.289,45
29/06/18  USD 9.211,99
07/07/18  USD 24.653,76
09/07/18  USD 99.701,32
15/08/18  USD 3.291,19

但是它并没有达到我的预期。我如何使它起作用?


现在尝试过:

@echo off
setlocal enabledelayedexpansion
for /f "tokens=3" %%i in ('findstr /i %1 c:\test\*.txt ^| findstr /i %2') do (
  set last_value=%%i
  )
set=!last_value!
for /f %%x in (%date%) do for /f "delims=.txt,  tokens=1" %%i in (%%x.txt) do echo %%x, %%i >> all_files.txt

我正在逐步进行,但是问题是脚本无法识别SET SearchFile=test.txt SET TmpSearchFile=output.txt SET String=%date% SET LineNum=3 FINDSTR /B /N "%String%" "%SearchFile%" > "%TmpSearchFile%" FOR /F "USEBACKQ TOKENS=2 DELIMS=: " %A IN (`"FINDSTR /B "%LineNum%:%String%" "%TmpSearchFile%""`) DO ECHO %~A %~A` ,我如何才能将当前单词替换为%date%的那一行?


只需尝试按日期对输出文件进行排序。

%date%

我模拟了将所有REM get first line: <all_files.txt set /p first= REM write it to a new file: >"test.txt" echo %first% REM sort the rest and append to the new file: <all_files.txt more +1|sort >>"test.txt" del /f /s /q all_files.txt >nul 2>nul 文件之一放入日期.txt的过程,但它没有按正确的顺序排序。 这是输出文件:

03/07/18

@Lotpings只是更改了您的最后一个脚本,但仍未按日期对其进行排序。

20/06/18  R$   2.211,63
22/06/18  R$   1.761,63
03/07/18  R$   3.042,21
25/06/18  R$   1.311,57
21/06/18  R$  22.842,88

查看输出文件:

@echo off & setlocal enabledelayedexpansion
mode 34,12

Set "OutFile=all_files.txt"
For %%A in (*.txt) do (
    for /f "tokens=1,3" %%T in ('findstr "^" "%%~fA"') do (
       set "USD=         %%U"
       set "LastDate=!ThisDate!"
       set "ThisDate=%%T"
    )
    set "Out=!USD:~0,-5!.!USD:~-5,3!,!USD:~-2,2!"
    set "Out=!Out: .=!"
    >>"%OutFile%" Echo=!LastDate:~0,2!-!LastDate:~3,2!-20!LastDate:~6,2!  USD !OUT:~-10!
)

就像你给我看的一样,但是对我没有排序。

4 个答案:

答案 0 :(得分:2)

修改为从最后一行的第二行获取日期 EDIT2更改了输出日期模式

:: Q:\Test\2018\06\27\SO_51064650.cmd
@echo off & setlocal enabledelayedexpansion

Set "OutFile=all_files.txt"
For %%A in (*.txt) do (
    for /f "tokens=1,3" %%T in ('findstr "^" "%%~fA"') do (
       set "USD=         %%U"
       set "LastDate=!ThisDate!"
       set "ThisDate=%%T"
    )
    set "Out=!USD:~0,-5!.!USD:~-5,3!,!USD:~-2,2!"
    set "Out=!Out: .=!"
        >>"%OutFile%" Echo=20!LastDate:~6,2!-!LastDate:~3,2!-!LastDate:~0,2!  USD !OUT:~-10!
)

带有模拟源文件USD * .txt的示例输出:

您将获得正确对齐(可排序)的输出:

> sort all_files.txt
2018-06-20  USD   2.211,63
2018-06-24  USD   8.289,45
2018-06-29  USD   9.211,99
2018-07-07  USD  24.653,76
2018-07-09  USD  99.701,32
2018-08-15  USD     291,19
2018-08-15  USD     291,19
2018-08-15  USD   3.291,19

答案 1 :(得分:2)

由于这是一项有趣的任务,我也必须为此编写脚本(请参见所有解释性的rem备注):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_ROOT=%~dp0." & rem // (directory containing the text files to process)
set "_MASK=*.txt"  & rem // (file name pattern for the text files to process)
set "_LIST=all_files.txt" & rem // (name or path of the resulting text file)
set "_TEMP=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (name or path to temporary file)
set "_CURR=USD"    & rem // (currency symbol or abbreviation to be returned)
set /A "_LPAD=0"   & rem // (minimal character width of the returned amount)

rem // Apply default values, if applicable:
if not defined _LIST set "_LIST=con"
if defined _CURR set "_CURR=%_CURR% "

rem // Temporarily change to directory containing the text files:
pushd "%_ROOT%" && (
    rem // Write output to temporary text file:
    > "%_TEMP%" (
        rem // Resolve path of resulting text file:
        for %%E in ("%_LIST%") do (
            rem // Loop through all text files sorted by ages:
            for /F "delims= eol=|" %%F in ('dir /B /A:-D /O:D "%_MASK%"') do (
                rem // Exclude resulting text file if it is in same location:
                if /I not "%%~fF"=="%%~fE" (
                    rem // Initialise variables for date and amount:
                    set "DAT=" & set "VAL=" & set "PRE=" & set "KEY="
                    rem // Iterate through lines of current text file:
                    for /F "usebackq tokens=1,3" %%G in ("%%~F") do (
                        rem // Store certain token (amount if last line):
                        set "VAL=%%H"
                        rem // Delay storage of another token (date):
                        setlocal EnableDelayedExpansion
                        (
                            for /F "tokens=1-3 delims=/" %%J in ("!DAT!") do (
                                endlocal
                                set "PRE=%%J/%%K/%%L"
                                rem // Build sortable date format (sort key):
                                if %%L lss 70 (
                                    set "KEY=20%%L/%%K/%%J"
                                ) else (
                                    set "KEY=19%%L/%%K/%%J"
                                )
                            )
                        ) || endlocal
                        set "DAT=%%G"
                    )
                    rem // Check whether date and amount tokens are found:
                    if defined PRE if defined VAL (
                        setlocal EnableDelayedExpansion
                        rem /* Convert amount to decimal number with digit grouping
                        rem    of thousands in a separate sub-routine: */
                        call :CONV STR "!VAL!" !_LPAD!
                        rem // Return resulting string:
                        echo(!KEY!  !PRE!  !_CURR!!STR!
                        endlocal
                    )
                )
            )
        )
    )
    rem // Write output to resulting text file:
    > "%_LIST%" (
        rem // Read sorted temporary text file and split off sort key:
        for /F "tokens=1*" %%K in ('sort "%_TEMP%"') do (
            rem // Return remaining string:
            echo(%%L
        )
    )
    rem // Clean up temporary file:
    del "%_TEMP%"
    popd
)

endlocal
exit /B


:CONV  <rtn_string>  <val_amount>  <val_width>
    ::::Sub-routine to convert a pure natural integer number to a fractional number
    ::::with two decimal places and with digits grouped to thousands. If the input
    ::::value contains characters other than decimal digits, it is returned as is.
    ::::PARAMETERS:
    ::::  <rtn_string>  name of variable to receive the resulting output string;
    ::::  <val_amount>  the input value to be converted;
    ::::  <val_width>   minimal character width of the output string; if greater
    ::::                than zero, the output string is padded on the left with
    ::::                spaces to take at least as many characters specified;
    setlocal DisableDelayedExpansion
    set "#RES=%~1"
    set "AMT=%~2"
    set "WID=%~3"
    rem // Convert width argument to an integer number:
    set /A "WID+=0"
    rem /* Check whether the input value contains characters other than decimal
    rem    digits and skip processing in case: */
    for /F "delims=0123456789 eol=0" %%Z in ("%AMT%") do (
        set "SEP=%AMT%"
        goto :QUIT
    )
    rem // Extract fractional part from input value:
    set "AMT=00%AMT%"
    set "FRA=%AMT:~-2%"
    rem // Remove trailing zeros from integer part:
    for /F "tokens=* delims=0" %%Z in ("%AMT:~,-2%") do set "AMT=%%Z"
    if not defined AMT set "AMT=0"
    rem // Do digit grouping to thousands in a loop from right to left:
    set "SEP=."
    :LOOP
    if not "%AMT:~,-3%"=="" (
        set "SEP=.%AMT:~-3%%SEP%"
        set "AMT=%AMT:~,-3%"
        goto :LOOP
    )
    rem // Assemble converted value:
    set "SEP=%AMT%%SEP:~,-1%,%FRA%"
    rem // Pad value to the left with spaces if a positive width is given:
    if %WID% leq  0 goto :QUIT
    if %WID% gtr 24 set "WID=24"
    setlocal EnableDelayedExpansion
    if "!SEP:~,-%WID%!"=="" (
        set "SEP=                        !SEP!"
        set "SEP=!SEP:~-%WID%!"
    )
    endlocal & set "SEP=%SEP%"
    rem // Return (potentially) converted and padded output value:
    :QUIT
    (
        endlocal
        set "%#RES%=%SEP%"
    )
    exit /B

此脚本的优点是:

  • 不处理目标位置中已经存在的输出文件;
  • 分组为数千的数字不限于一定数量的输入数字;
  • 按日期升序对输出文件中的条目进行排序;

答案 2 :(得分:1)

@SETLOCAL ENABLEDELAYEDEXPANSION
@ECHO OFF

FOR %%f in (*.txt) DO (
    SET PREV_DATE_STAMP=
    SET DATE_STAMP=
    SET AMOUNT=
    FOR /F "tokens=1,3" %%a IN (%%f) DO (
        REM  Keep the two most recent stamps.
        SET "PREV_DATE_STAMP=!DATE_STAMP!"
    SET "DATE_STAMP=%%~a"
        REM  Keep the last amount datum.
        SET "AMOUNT=%%~b"
    )

    REM  Format the amount. This is tricky to do intelligently with CMD.
    SET /A "NUM_AMOUNT=!AMOUNT!"
    REM   -> #########,##
    SET FMT_AMOUNT=!AMOUNT:~0,-2!,!AMOUNT:~-2!
    REM   Add the digit grouping for thousands
    IF !NUM_AMOUNT! GEQ 10000 SET "FMT_AMOUNT=!FMT_AMOUNT:~0,-6!.!FMT_AMOUNT:~-6!"
    REM   Add the digit grouping for millions
    IF !NUM_AMOUNT! GEQ 10000000 SET "FMT_AMOUNT=!FMT_AMOUNT:~0,-10!.!FMT_AMOUNT:~-10!"
    REM   CMD only uses 32-bit integers, so you millions are the largest value you'll ever get (last 2 digits are hundredths)
    SET "FMT_AMOUNT=          !FMT_AMOUNT!"

    @ECHO !PREV_DATE_STAMP!   USD !FMT_AMOUNT:~-12!
)

此脚本完成您描述的工作。您所需要的CMD特别熟练,

  • 格式化数字
  • 用小数处理
  • 以不同的行格式处理
  • 效率

但是,考虑到您所做的简化假设,就可以做到。

    日期和下一列之间的
  • 空格分隔符
  • 最后一条记录的前四列之间的空格分隔符
  • 金额不太大(<= 2 ^ 29)

更新:添加了对* .txt的循环(并在循环内对变量使用了延迟扩展),并结合了@LotPings的右对齐想法(他为+1)。

答案 3 :(得分:1)

这里有一个PowerShell解决方案,它提供了4种格式化USD列的替代方法:

## Q:\Test\2018\06\27\SO_51064650.ps1
$InFile  = ".\*.txt"
$OutFile = "all_files.txt"

$DateUSD = ForEach ($File in (Get-ChildItem $InFile -File -Exclude $OutFile)){
    $Text = (Get-Content $File | Select-Object -Last 2)
    $USD  = [Decimal](($Text[1] -split ' +')[2]/100)
    [PSCustomObject]@{
         Date = ($Text[0] -split ' +')[0]
         USD1 = $USD
         USD2 = "{0,11:C}" -f $USD
         USD3 = "{0,9:N}" -f $USD
         USD4 = "USD {0,9:N}" -f $USD
    }
}
$DateUSD | Sort-Object {[DateTime]::ParseExact($_.Date,'dd/MM/yy',$Null)} |
  ft -auto  | Out-String | Set-Content $OutFile

  • USD1的格式为十进制数字(不包含千位分隔符)
  • USD2的格式为货币(我的设置为€)
  • USD3是数字格式(带千位分隔符)
  • USD4是以USD为前缀的纯文本

> Get-Content .\all_files.txt

Date         USD1 USD2        USD3      USD4
----         ---- ----        ----      ----
20/06/18  2211,63  2.211,63 €  2.211,63 USD  2.211,63
24/06/18  8289,45  8.289,45 €  8.289,45 USD  8.289,45
29/06/18  9211,99  9.211,99 €  9.211,99 USD  9.211,99
07/07/18 24653,76 24.653,76 € 24.653,76 USD 24.653,76
09/07/18 99701,32 99.701,32 € 99.701,32 USD 99.701,32
15/08/18   291,19    291,19 €    291,19 USD    291,19
15/08/18  3291,19  3.291,19 €  3.291,19 USD  3.291,19
15/08/18   291,19    291,19 €    291,19 USD    291,19