通过目录循环并从今天创建的文件中提取数据

时间:2014-11-21 01:53:55

标签: batch-file for-loop grep cygwin

我有一些* .XML文件位于目录及其子目录中。这些文件不时增加,因为定期使用win批处理脚本,我在提取XML文件内容后将其用于其他任务。

我知道如何遍历所有文件并提取所需的数据,但我不知道的是如何只遍历今天创建的文件,以便我可以从中提取我需要的内容。 / p>

以下是我从所有文件中提取数据的行为:

1 - 使用" Grep"工具,提取文件'内容

grep -r -hi --include="*.XML" "Pattern" > My.Data

2 - 在.XML文件中循环,并将它们合并为一个文件!

For /R %%X in (*.XML) Do @Type "%%X" >> My.Data

是的我知道在我有Grep时使用第二个命令有点奇怪!但实际上,我需要99%的每个文件内容,所以两种方式对我来说几乎都是一样的。

至于我的问题,我认为如果有人可以帮我修改上面的一个命令,循环使用今天创建的xml文件,那将会很棒。但是,如果它不可能,或者某人有更好的方法,请不要犹豫,分享它。顺便说一下,我在我的系统上安装了Cygwin(win7-64)

非常感谢你们, 我希望像往常一样从这里得到正确答案。 - 卡里姆:)

3 个答案:

答案 0 :(得分:1)

我认为您正在寻找的命令是forfiles。输入forfiles /?以获取完整语法。要仅查看今天已修改的文件,请执行以下操作:

forfiles /s /m *.xml /d +0 /c "cmd /c grep -hi ^"pattern^" @file >>\path\to\My.Data"

修改:正如卡里姆指出的那样,forfiles根据last modified日期匹配文件。他希望根据created日期匹配文件。


要获取文件的创建日期,请使用dir /tc并使用for循环捕获它:

@echo off
setlocal

:: get recursive list of XML files
:: note: In US locale, a dir listing has 5 columns:
:: MM/DD/YYYY  HH:MM  AM/PM  size  filename
:: With "tokens=1,4*":
::   %%a captures date
::   %%b is throwaway (capturing file size)
::   %%c captures the filename with spaces

for /f "tokens=1,4*" %%a in ('dir /s /tc *.XML') do (

    rem :: In US locale, %date% is in format "Day-of-week MM/DD/YYYY"
    rem :: If your locale doesn't list date last, see
    rem :: http://www.dostips.com/DtTipsStringManipulation.php
    rem :: for an explanation of string manipulation.

    if "%%a" equ "%date:* =%" (

        rem :: do stuff.
        grep "Pattern" "%%c" >> My.Data

    )
)

答案 1 :(得分:0)

@echo off
    setlocal enableextensions disabledelayedexpansion

    (   (for /r %%a in (*.xml) do (echo(%%~ta_%%~fa)) ^
        |(for /f "tokens=1,* delims=_" %%a in ('findstr /l /b /c:"%date%"') do (type "%%b")) ^
        |grep -ih "pattern"
    ) > My.Data

代码只是一个包含三个命令的管道。

第一个for循环将遍历当前文件夹和子文件夹(*.xml)中的/r个文件,并输出文件的日期和时间(%%~ta),下划线(用作分隔符)和文件的全名(%~fa)。

第二个for循环将过滤此列表以仅获取具有今天日期的文件(这在上一步中尚未完成,以避免操作处理包含星期几的日期格式),拆分记录(使用下划线作为分隔符)和type文件的内容。

第三个命令是grep,它将过滤数据。

所有生成的内容都会重定向到输出文件。

已编辑 Aggg !!!创立日期 !!!如果不使用脚本引擎,我看到的唯一方法是处理dir命令的输出,这不是更结构化的数据源。

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Temp files needed
    set "tempList=%temp%\%~nx0.%random%.list.tmp"
    set "tempData=%temp%\%~nx0.%random%.data.tmp"

    rem Retrieve data from system to be able to parse the dir command
    set "colSkip="
    for /f "tokens=1-10" %%a in ('dir /ad ^| findstr /r /c:"> *\.\."') do (
        if not defined colSkip if "%%a"=="<DIR>" set "colSkip=1"
        if not defined colSkip if "%%b"=="<DIR>" set "colSkip=2"
        if not defined colSkip if "%%c"=="<DIR>" set "colSkip=3"
        if not defined colSkip if "%%d"=="<DIR>" set "colSkip=4"
        if not defined colSkip if "%%e"=="<DIR>" set "colSkip=5"
        if not defined colSkip if "%%f"=="<DIR>" set "colSkip=6"
        if not defined colSkip if "%%g"=="<DIR>" set "colSkip=7"
        if not defined colSkip if "%%h"=="<DIR>" set "colSkip=8"
        if not defined colSkip if "%%i"=="<DIR>" set "colSkip=9"
        if not defined colSkip if "%%j"=="<DIR>" set "colSkip=10"
    )
    for /f %%a in (".") do set "drive=%%~da"
    for /f %%d in ("%date%") do set "today=%%d"

    rem Execute a dir command to find the list of files that will be processed
    echo ... Searching files
    > "%tempList%" (
        dir /s /tc /a-d *.xml | findstr /b /r /c:"%date%" /c:" [^ ].*:\\.*"
    ) 

    rem Process the list to find final file names with full path
    echo ... Processing file list
    set "folder="
    > "%tempData%" (
        for /f "usebackq delims=" %%a in ("%tempList%") do for /f %%b in ("%%a") do if not "%%b"=="%today%" (
            for /f "tokens=2 delims=:" %%c in ("%%a") do set "folder=%drive%%%c"
        ) else for /f "tokens=%colSkip%,*" %%c in ("%%a") do (
            set "file=%%d"
            setlocal enabledelayedexpansion
            echo ...... found: !folder!\!file! > con
            type !folder!\!file!
            endlocal
        )
    )

    rem Extract the final needed data 
    echo .... extracting data
    > "My.Data" (
        grep -ih "pattern" "%tempData%"
    )

    rem Clean temp files    
    del /q "%tempData%" >nul 2>nul 
    del /q "%tempList%" >nul 2>nul 

    exit /b

代码太多,但应该独立于日期格式,星期几或上午/下午时间工作。第一个for循环将只搜索dir命令输出中文件名所在的列。

使用所有必要的先前信息,检索文件列表。配置为检索创建日期的递归dir命令用于列出当前文件夹下的所有.xml文件,findstr将过滤此列表以仅获取具有今天日期的文件或带有文件夹名称的行。此信息将发送到临时文件(不知道要检索的信息量,此方法比for /f更稳定)

现在我们有一个文件夹和文件列表。对于输入文件(%%a)中的每一行,确定该行是否包含文件夹的名称或文件(%%b)。如果它是一个文件夹,则检索其名称(%%c)并存储以便以后连接到文件名。如果它是文件,则从其余列中提取文件名(%%d),连接到文件夹名称并转储文件的内容。所有文件的输出将被发送到临时文件,稍后将对其进行处理以仅检索所需信息。

为什么所有这些代码?它应该是与语言环境无关的。只有一个dir命令用于检索要处理的完整文件列表。找到的每个文件都有一个type,但所有数据只有一个grep

答案 2 :(得分:0)

你们都考虑过这个吗?它肯定会告诉你今天创建的文件。我不确定它是最终的答案,但也许你一直在研究它的人可以从这里建立起来。我自己在修改与创建日期方面遇到了麻烦,所以有兴趣研究它。它只是this的略微修改版本。

需要在FOR / r循环中输入正确的路径。

@echo off
SETLOCAL EnableExtensions EnableDelayedExpansion

    :: Convert today's date to julian format
    CALL :DateToJDN "%DATE%" JDNToday

        FOR /r "PathToXMLfiles" %%a IN (*.xml) DO (
            :: The dir /t:c gets creation date
            FOR /f "tokens=1,4*" %%b IN ('dir /t:c "%%~a"^|findstr "^[0-9]"') DO (
               :: Convert file creation date to julian
               CALL :DateToJDN "%%b" filedate
               SET /a diffdays=JDNToday-filedate
               IF !diffdays! EQU 0 echo created today!
            )
         )
        GOTO :eof

:DateToJDN "DD mm/dd/yyyy" jdn=
REM Convert dates to Julian
    setlocal
    set date=%~1
    set /A yy=%date:~-4%, mm=1%date:~-10,2% %% 100, dd=1%date:~-7,2% %% 100
    set /A a=mm-14, jdn=(1461*(yy+4800+a/12))/4+(367*(mm-2-12*(a/12)))/12-(3*((yy+4900+a/12)/100))/4+dd-32075
    endlocal & set %2=%jdn%
    exit /B
顺便说一句,这是12小时的时间。对于24小时的时间,更改&#34;令牌= 1,4 *&#34; to&#34; tokens = 1,3 *&#34;。