2016-12-20 5 views
1

過去の単純なバッチファイルを使用して、単一のtxtファイル内の文字列を検索し、複数のtxtファイルをマージしましたが、これは少し複雑です。開始。ここでファイル名と複数の文字列を返すバッチファイル

は私がやろうとしています何のブレークダウンです:

は300+のtxtファイル

で一つのフォルダは、各txtファイル」は、文字列の出現の少なくとも一方が、多分数百を持っている持っていますdocumentID: "、それに続いて6つのチャーターがあります。

txtファイルやCSV、TXTファイルのファイル名を持つ、と毎回のための文字列「文書IDが」したいtxtファイルに発見された - 6次の文字が

例:

jsmith.txt:

<type>not needed</type> 
<version>1.0</version> 
not needed,not needed, not needed, documentID:NEED01, not needed 
not needed,not needed, not needed, documentID:NEED02, not needed 

jdoe.txt

<type>not needed</type> 
<version>1.0</version> 
not needed,not needed, not needed, documentID:NEED03, not needed 

所望の出力:

new.txt

jsmith, NEED01, NEED02 
jdoe, NEED03 
+1

が、これはハイブリッドXMLファイルのいくつかの種類ですか?各文書IDはそれ自身の行にありますか?それは常に4番目のコンマで区切られたフィールドにありますか? – Squashman

+0

はいこれはxmlファイルです(ただし、出力が必要なため、txtファイルにする必要があります)。必要なコンテンツは必ずしも4番目のフィールドにあるとは限らず、時には多くのフィールドや多くのフィールドがあります。 – PaperClip

答えて

1
@echo off 
setlocal EnableDelayedExpansion 

for %%A in (*.txt) do (
    set "out=" 
    for /f "usebackq tokens=*" %%B in (`findstr /rc:"documentID:[^^,]*" "%%A"`) do (
     set "str=%%B" 
     set "val=!str:*documentID:=!" 
     set "tail=!val:*,=!" 
     call set "res=%%val:,!tail!=%%" 
     set "out=!out!, !res!" 
    ) 
    echo %%~nA!out! 
) 

endlocal 


Rem For mentioned jsmith.txt and jdoe.txt will output 
Rem 
Rem jdoe, NEED03 
Rem jsmith, NEED01, NEED02 

現在のディレクトリ内のすべてのファイル*.txt〜第forループ反復します。

第2のforループは、findstrコマンドの出力を反復します。

findstrコマンドは、documentID:*,パターンの文字列を探します。 documentIDという単語では大文字と小文字が区別されます。シンボルは,のパターンに従う必要があります。

set "val=!str:*documentID:=!"コマンドは、見つかった文字列の先頭と、documentID:という単語を消去します。

パターンの後のすべてのシンボルがset "tail=!val:*,=!"コマンドで受信されます。

call set "res=%%val:,!tail!=%%"コマンドは、documentID:ワードの直後に値を抽出します。

+0

良い解決策+1、tailとresの代わりに '!val:〜0,6!'を使わないのはなぜですか? – LotPings

+0

時期尚早最適化:) IDの長さを可変にできる場合。 –

+0

入力いただきありがとうございます!来週火曜日にこれを試してみましょう(休暇を過ごすために出発します)、それがうまくいく方法であなたに戻ってきます....しかしあなたの説明はかなり意味があります。ありがとう! – PaperClip

0

次のスクリプトは、あなたが望むものを、すべての必要な文字列の部分を想定して、独自の行にあるん

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 

rem // Define constants here: 
set "_LOCATION=%~dp0." & rem // (path to the directory containing the input files) 
set "_PATTERN=*.txt"  & rem // (pattern the input files need to match) 
set "_PREFIX=documentID:" & rem // (string that precedes the needed string portion) 
set "_SEPAR=, "   & rem // (field separator for both input and output files) 

rem // Loop through all matching input files: 
for %%F in ("%_LOCATION%\%_PATTERN%") do (
    rem // Initialise collection variable with the name of the currently iterated file: 
    set "COLLECT=%%~nxF" 
    rem // Search current file for predefined prefix and loop over all applicable lines: 
    for /F delims^=^ eol^= %%L in ('findstr /C:"%_PREFIX%" "%%~F"') do (
     rem // Store currently processed line: 
     set "ITEM=" & set "LINE=%%L" 
     rem // Toggle delayed expansion to not lose any exclamation marks `!`: 
     setlocal EnableDelayedExpansion 
     rem /* Split off the prefix and everything in front of it, then split off the 
     rem next separator (regard first character only) and everything behind: */ 
     for /F "delims=%_SEPAR:~,1% eol=%_SEPAR:~,1%" %%K in ("!LINE:*%_PREFIX%=!") do (
      endlocal 
      set "ITEM=%%K" 
      setlocal EnableDelayedExpansion 
     ) 
     rem /* Append extracted string portion to collection variable and transport the 
     rem result over the `endlocal` barrier using the `for /F` command: */ 
     for /F "delims= eol=:" %%K in ("!COLLECT!%_SEPAR%!ITEM!") do (
      endlocal 
      set "COLLECT=%%K" 
     ) 
    ) 
    rem // Return the collected line for the currently iterated file: 
    setlocal EnableDelayedExpansion 
    echo(!COLLECT! 
    endlocal 
) 

endlocal 
exit /B 

テキストファイル、使用リダイレクトで結果を保存するには、例えば、スクリプトはmerge-files.batとして保存され、結果のテキストファイルがD:\result\new.csvである必要があり、このようなスクリプトを呼び出します。

merge-files.bat > "D:\result\new.csv" 
関連する問題