如何从文本文件中提取某些文本并使用此文本替换另一个文件中的关键字?

时间:2015-01-08 20:55:55

标签: batch-file sql-scripts

长话短说我有一个SQL脚本,当一个动作崩溃时我运行,我有一个日志,我有我需要的所有信息,我只是用日志文件中的文本替换这个SQL脚本的某些部分。

我的问题:有没有办法可以从批处理文件中执行此操作?

实施例

日志文件包含查询ID:123456和EntityID:654321,23123432,345345435,435435,438980943等。

我有SQL脚本,我替换了#34; QueryID"使用日志中的查询ID号,我也想替换" entityID"对于日志文件中的所有entityid,通常有几百个。

这是SQL脚本

select * 
from search_results 
where search_id = ***query_id*** 
  and entity_id in (select entity_id 
                    from search_results 
                    where search_id = ***query_id***
                      and entity_id in (***entityID***))

上面是我运行的SQL脚本,我想将 Query_id 替换为我拥有的日志文件中的查询ID,然后替换 Entity_ID ,来自同一日志文件的实体ID

我一直试图找到一种解决这个问题的方法,但我已经陷入困境,我使用以下操作将实体ID提取到一个文件然后我只是复制并粘贴它们到SQL脚本

@ECHO OFF
for /f "tokens=4 delims=:" %%G in ('TYPE logfile.txt ^|FIND /i "EntityID"') do (
    ECHO %%G,>>entity.txt
)

我可以对查询ID执行相同操作,但因为只有一个ID我只是复制&粘贴它。

简而言之,我想在目录/文件中放置一个日志,然后运行一个Bat文件来生成SQL脚本(在文本文件中)。

任何帮助将不胜感激:)

额外信息

我必须运行这个脚本来弄清楚eshot中的人是什么,eshot已经/没有被发送给我所以我可以删除那些已经发送给他们的eshot并将其从列表中删除的人在SQL中,eshot可以再次设置,人们不会收到很多电子邮件。

QueryID是列出电子邮件的列表的ID,而entityID是列表中电子邮件地址的ID。

因此,简而言之,sql脚本找到电子邮件地址列表(通过QueryID),然后显示eshot已发送到的电子邮件地址(通过日志文件中的entityID'),这样我就可以从列表并重新发送eshot,人们不会收到两封电子邮件。

当人们的电子邮件地址中有愚蠢的字符时,这通常会失败。

此处的日志文件已删除数据敏感信息。

>  ==========================================================================================
>     
>     ------------------------------------------------------------------------------------------
>     Domain      :10007
>     User        :10725
>     Language    :1
>     Entity      :0
>     Role        :-1
>     View        :8997749 ()
>     Region      :8998836 ()
>     Control     :
>     Date/Time   :5 janvier 2015 15:49:33 UTC
>     ==========================================================================================
>     [15:49:33 UTC] TotalQueryIDs :1:
>     [15:49:33 UTC] User :10725:
>     [15:49:33 UTC] Template :20005406:
> !!!    [15:49:33 UTC] queryID :96566:
>     [15:49:33 UTC] QueryCount :781:
>     [15:49:33 UTC] Count :1:
> !!!    [15:49:33 UTC] EntityID :49891:
>     [15:49:33 UTC] Contact :49891:
>     [15:49:33 UTC] Today :05/01/15:
>     [15:49:33 UTC] Time :16:49:
>     [15:49:33 UTC] EmailID ::
>     [15:49:33 UTC] posOfSign :7:
>     [15:49:33 UTC] posOfSign :7:
>     [15:49:33 UTC] posOfDot :10:
>     [15:49:33 UTC] emailValidity ::
>     [15:49:33 UTC] flag ::
>     [15:49:33 UTC] Language :English:
>     [15:49:33 UTC] Template1 :COBE8:
>     [15:49:33 UTC] flag ::
>     [15:49:33 UTC] --<*> RSH <*>--
>     [15:49:33 UTC] TempName ::
>     [15:49:33 UTC] DocCount :96:
>     [15:49:33 UTC] BeforeAdd ::
>     [15:49:33 UTC] AfterAdd ::
>     [15:49:33 UTC] afterIF ::
>     [15:49:33 UTC] preview :N:
>     [15:49:33 UTC] preview :N:
>     [15:49:34 UTC] DocCount :1:
>     [15:49:34 UTC] countofATT ::
>     [15:49:34 UTC] Today :05/01/15:
>     [15:49:34 UTC] Time :16:49:
>     [15:49:34 UTC] EMAILSEND ::
>     [15:49:34 UTC] preview :N:
>     [15:49:34 UTC] Role :111:
>     [15:49:34 UTC] e1 ::>     
>     [15:49:34 UTC] e1 ::
>     [15:49:34 UTC] DocCount :96:
>     [15:49:34 UTC] DocCount :96:
>     [15:49:34 UTC] e1 ::
>     [15:49:34 UTC] countofATT ::
>     [15:49:34 UTC] DocCount :1:
>     [15:49:34 UTC] e1 ::
>     [15:49:34 UTC] --<*> About to Save Journal <*>-->     
>     [15:49:34 UTC] --<*> Journal Saved <*>--
>     [15:49:34 UTC] EmailID ::
>     [15:49:34 UTC] Count :2:
> !!!    [15:49:34 UTC] EntityID :49903:
>     [15:49:34 UTC] Contact :49903:
>     [15:49:34 UTC] Today :05/01/15:
>     [15:49:34 UTC] Time :16:49:
>     [15:49:34 UTC] EmailID ::
>     [15:49:34 UTC] posOfSign :3:
>     [15:49:34 UTC] Eshot :Y:
>     [15:49:34 UTC] posOfSign :3:
>     [15:49:34 UTC] posOfDot :11:
>     [15:49:34 UTC] emailValidity ::
>     [15:49:34 UTC] flag ::
>     [15:49:34 UTC] Phone ::
>     [15:49:34 UTC] Language :English:
>     [15:49:34 UTC] Template1 :COBE8:
>     [15:49:34 UTC] flag ::

以下是SQL脚本应该是什么样子的示例

    select * from search_results where search_id =96566 and
entity_id in (select entity_id from search_results where search_id =96566
And entity_id in(49891,49903,51404,137395,137492,))

感谢所有帮助的人,非常感谢。


更新

我使用以下内容(感谢@Keeghan McGarry)并得到我想要的但实体ID只显示列表中的最后一个,是否有办法获取所有实体ID&#39; s现身, FYI 该日志名为bo.txt,脚本转到sql.txt

@ECHO OFF  
FOR /F "tokens=4 delims=:" %%e IN ('TYPE bo.txt ^|FIND /i "EntityID"') DO SET entity=%%e
FOR /F "tokens=4 delims=:" %%q IN ('TYPE bo.txt ^|FIND /i "queryID"') DO SET query=%%q

ECHO select * from search_results where search_id =%query% and entity_id in >> sql.txt  
ECHO (select entity_id from search_results where search_id =%query%>> sql.txt  
ECHO And entity_id in>> sql.txt  
ECHO (%entity%))>> sql.txt

以上给出了以下内容,但应该有这些实体ID 49891,49903,51404,137395,137492,

  

从search_results中选择*,其中search_id = 96566和entity_id in   (从search_results中选择entity_id,其中search_id = 96566和   entity_id in(137492))

非常感谢所有帮助。

3 个答案:

答案 0 :(得分:0)

我的建议是为您的EntityID和QueryID设置一个变量,而不是输出到一个单独的文件。这样您就可以在一个文件中回显整个SQL脚本,并在需要的位置使用变量。一个非常简短的例子(未经测试,因为我没有你的LogFile.txt):

@ECHO OFF  
FOR /F "tokens=4 delims=:" %%F IN ('TYPE logfile.txt ^|FIND /i "EntityID"') DO SET SET entity=%%F  
FOR /F "***Need to set these***" %%G IN ('TYPE logfile.txt ^|FIND /i "query_ID"') DO SET SET query=%%G  
ECHO select * from search_results where search_id = %query% and entity_id in > query.txt  
ECHO (select entity_id from search_results where search_id = %query% >> query.txt  
ECHO And entity_id in >> query.txt  
ECHO (%entity%)) >> query.txt 

您只需要为查询ID添加正确的令牌和delim,然后就可以了。如果您可以提供示例 LogFile.txt ,那么我可以测试/扩展此代码。

希望这会有所帮助

修改

根据编辑过的问题,让每个entityID将查询输出放在FOR循环中。

@ECHO OFF  
setlocal enabledelayedexpansion

FOR /F "tokens=4 delims=:" %%q IN ('TYPE bo.txt ^|FIND /i "queryID"') DO SET query=%%q
FOR /F "tokens=4 delims=:" %%e IN ('TYPE bo.txt ^|FIND /i "EntityID"') DO (
    SET entity=%%e
    ECHO select * from search_results where search_id =%query% and entity_id in >> sql.txt  
    ECHO (select entity_id from search_results where search_id =%query%>> sql.txt  
    ECHO And entity_id in>> sql.txt 
    ECHO (!entity!^)^)>> sql.txt
    ECHO.>> sql.txt
)

正如你所看到的那样,我切换了FOR循环的顺序,现在queryID首先出现,而sql.txt的输出位于另一个循环中,所以每次找到一个entityID时它都会输出它。添加的ECHO.>> sql.txt是为了分解sql.txt中的每个查询。

答案 1 :(得分:0)

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "destdir=U:\destdir"
SET "queryid="
FOR /f "tokens=4,5 delims=[]:" %%a IN (
  'type q27849431.txt^|findstr /i /l /c:" queryID " /c:" EntityID "'
 ) DO (
 IF "%%a"==" queryID " CALL :generate %%b
 IF "%%a"==" EntityID " SET "entityids=!entityids!,%%b"
  )
)
CALL :generate 0

GOTO :EOF

:generate
IF NOT DEFINED queryid GOTO first
SET "entityids=%entityids: =%"
(
 ECHO select * from search_results where search_id = %queryid% and entity_id in 
 ECHO (select entity_id from search_results where search_id = %queryid%
 ECHO And entity_id in 
 ECHO (%entityids:~1%^)^)^)
)>"%destdir%\query%queryid%.sql"

:first
SET /a queryid=%1
SET "entityids="
GOTO :eof

嗯 - 提供了一些数据。我相信日志行实际上开始&gt; Spaces 并且目标行包含!!!非常不可能,所以我从数据中删除了这些并放置了导致我的测试名为q27849431.txt的文件。

我还假设有一个要处理的日志文件(q27849431.txt)并且其结构是

[15:49:33 UTC] TotalQueryIDs :1:
[15:49:33 UTC] queryID :96577:
[15:49:33 UTC] EntityID :49891:
[15:49:34 UTC] EntityID :49903:
[15:49:33 UTC] TotalQueryIDs :1:
[15:49:33 UTC] queryID :96588:
[15:49:33 UTC] EntityID :49896:
[15:49:34 UTC] EntityID :49943:
[15:49:34 UTC] posOfSign :3:

(显示重要和随机的行 - 尤其是包含重要字符串queryid的行,无论情况如何)

从那里开始,批处理是VB程序员的游戏。找到queryid,然后构建一个entityids字符串。每次queryid更改时输出一个新查询,一个用于日志文件末尾的运气(因为没有其他查询,但一个仍然累积但不输出)

每个sql都生成一个名称明显的文件。如果您希望将它们全部放在同一个文件中,请将>"%destdir%\query%queryid%.sql"更改为>>"whateverdestinationfilenameyouwant",但该构造将追加添加到任何现有"whateverdestinationfilenameyouwant",因此可能是一个想法在脚本开头删除"whateverdestinationfilenameyouwant"

答案 2 :(得分:0)

在每个人的帮助下,尤其是@magoo,我终于得到了答案:)

@ECHO OFF

setlocal enabledelayedexpansion

FOR /F "tokens=4 delims=:" %%q IN ('TYPE bo.txt ^|FIND /i "queryID"') DO (SET query=%%q)

    ECHO select * from search_results where search_id =%query% and entity_id in >> sql.txt  
    ECHO (select entity_id from search_results where search_id =%query%>> sql.txt  
    ECHO And entity_id in(>> sql.txt 

FOR /F "tokens=4 delims=:" %%e IN ('TYPE bo.txt ^|FIND /i "EntityID"') DO (SET entity=%%e
    ECHO !entity!>> sql.txt)
echo )) >>sql.txt

以上脚本生成以下SQL脚本:

select * from search_results where search_id =96566 and entity_id in   
(select entity_id from search_results where search_id =96566  
And entity_id in( 
49891
49903
51404
137395
137492
)) 

来自问题中的日志文件。

如果在运行脚本的其余部分之前已经存在,我将添加一行来查找和删除sql.txt,以免在同一文件中包含大量SQL脚本。

感谢所有帮助伙伴们