使用findstr csv文件

时间:2016-11-02 18:17:55

标签: csv batch-file cmd

我在本网站上没有找到关于编写此功能的任何内容。

这里有一部分信息,我希望如何完成。 日期总是在日期数据之后(如我的例子中所示)

Type, ID, HouseNu,TimeDepart,StartingAdress,EndingAdress, etc..
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 2 2016 12:00AM
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016 12:00AM

我想这样

Date,Type, ID, HouseNu,TimeDepart,StartingAdress,EndingAdress, etc..
Nov 2 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 2 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 2 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 2 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz
Nov 3 2016,Occ, 12345, 122 str xxx, 13:30, 77 Street xyz, 150 Street xyz

这可能吗?我知道“12:00 AM”将永远不会出现在我的数据中,除了日期时间。那么是否有可能使用findstr在数据下方找到日期并添加具有此日期的列,如果日期更改,日期也会更改?

我不知道我是否足够清楚!?如果没有,请评论。 我很感激你能给我这个问题的时间。

仅供参考,输出来自MS SQL数据库,我使用sqlcmd和存储过程导出所有数据。参数是日期,我在storec程序上做了“do while”以获得4天的数据。导出给了我一些使用批处理脚本删除的无用信息。但我不知道如何使用findstr添加列。

这里是我用来获取所有这些信息的代码:

del /q Results.csv
sqlcmd -S serveur -i C:\TA_UPS_Script\SqlScript.sql -o C:\TA_UPS_Script\Results.csv -s; -SServeur\XYZ -E
findstr /v "Changed database context to 'XYZ'." C:\TA_UPS_Script\Results.csv > C:\TA_UPS_Script\ETAPE1.csv
findstr /v "Warning"  C:\TA_UPS_Script\ETAPE1.csv > C:\TA_UPS_Script\ETAPE2.csv
findstr /v "Matricule"  C:\TA_UPS_Script\ETAPE2.csv > C:\TA_UPS_Script\ETAPE3.csv
findstr /v /c:"--------" C:\TA_UPS_Script\ETAPE3.csv > C:\TA_UPS_Script\ETAPE4.csv
del /q C:\TA_UPS_Script\ETAPE1.csv
del /q C:\TA_UPS_Script\ETAPE2.csv
del /q C:\TA_UPS_Script\ETAPE3.csv
del /q C:\TA_UPS_Script\Results.csv
type C:\TA_UPS_Script\ETAPE4.csv | repl "1899-12-30 " "" L > C:\TA_UPS_Script\ETAPE5.csv
type C:\TA_UPS_Script\ETAPE5.csv | repl ":00.000" "" L > C:\TA_UPS_Script\ETAPE6.csv
type C:\TA_UPS_Script\ETAPE6.csv | repl ".000" "" L > C:\TA_UPS_Script\ETAPE7.csv
del /q C:\TA_UPS_Script\ETAPE4.csv
del /q C:\TA_UPS_Script\ETAPE5.csv
del /q C:\TA_UPS_Script\ETAPE6.csv
type C:\TA_UPS_Script\Header.csv C:\TA_UPS_Script\ETAPE7.csv > C:\TA_UPS_Script\Results.csv
del /q C:\TA_UPS_Script\ETAPE7.csv

1 个答案:

答案 0 :(得分:1)

虽然你没有表现出任何自己的努力来解决你的任务,但我决定为此提供一个脚本,因为它对我来说似乎并不是一件轻而易举的事。所以这是代码,具有解释性注释:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE_IN=sample.csv" & rem // (input file)
set "_FILE_OUT=con"       & rem /* (output file; must not be equal to input file!
                            rem     state `con` to output to console) */
set "_FIELD=Date" & rem // (name of prepended field to be inserted into header)
set "_SEPAR=,"    & rem // (separator character; should be the `,`)
set "$HEADER=#"   & rem /* (defines whether a header is present in the input file;
                    rem     set to empty value in case no header is there) */

rem // Redirect all data to output file once to avoid multiple file accesses:
> "%_FILE_OUT%" (
    rem // Reset index counter:
    set /A "IDX=0"
    rem // Read input file line by line:
    for /F usebackq^ delims^=^ eol^= %%L in ("%_FILE_IN%") do (
        rem // Check whether header is available:
        if defined $HEADER (
            rem // Current line is the header, so prepend new field name:
            echo(%_FIELD%%_SEPAR%%%L
            rem // Reset header flag to not treat any more lines as header:
            set "$HEADER="
        ) else (
            rem // Current line is not the header, so capture it:
            set "LINE=%%L"
            rem // Check whether current line is one of the non-CSV lines:
            setlocal EnableDelayedExpansion
            rem Avoid trouble with pipe by temporarily doubling all ":
            set "LINE=!LINE:"=""!^"
            rem Avoid trouble with pipe by temporarily escaping all %:
            set "LINE=!LINE:%%=^%%!"
            (echo "!LINE!" | > nul find "%_SEPAR%") && (
                endlocal
                rem // Current line is standard CSV line, so increment index:
                set /A "IDX+=1"
                rem /* Store current line in array-like variable `ARRAY[]`;
                rem    use `for /F` loop to overcome `endlocal` barrier: */
                setlocal EnableDelayedExpansion
                for /F "delims=" %%E in ("ARRAY[!IDX!]=!LINE!") do (
                    endlocal
                    set "%%E"
                )
            ) || (
                endlocal
                rem // Current line is non-CSV line, so extract date:
                for /F "tokens=1-3" %%I in ("%%L") do (
                    rem // The first three tokens constitute the date:
                    set "LINE=%%I %%J %%K"
                )
                rem // Return all stored CSV lines, preceded by found date:
                setlocal EnableDelayedExpansion
                for /L %%K in (1,1,!IDX!) do (
                    echo(!LINE!%_SEPAR%!ARRAY[%%K]!
                )
                endlocal
                rem // Reset index counter:
                set /A "IDX=0"
            )
        )
    )
    rem /* Return remaining stored CSV lines, preceded by an empty field,
    rem    for them not to be lost in case of a badly formatted file: */
    setlocal EnableDelayedExpansion
    for /L %%K in (1,1,!IDX!) do (
        echo(%_SEPAR%!ARRAY[%%K]!
    )
    endlocal
)

endlocal
exit /B

基本上,此批处理文件缓冲类似于数组的变量ARRAY[]中的所有行,直到遇到非CSV行(不包含,),然后输出所有缓存行按非CSV行的日期部分。

这种方法对于出现在文件中的各种特殊字符应该是健壮的。