2012-03-16 5 views
0

バッチファイルを処理して、2行のテキストを1行にまとめようとしています。最初はファイル名です。 2番目は "To:"で始まるテキストの最初の行です。私は時間のために苦労してきた、これは私の知る限り得ているようです:バッチ - ループ内で1行に2つのテキストを組み合わせる

@echo off 
IF EXIST fullnames.txt DEL fullnames.txt 
FOR /F %%g IN ('dir /b *.eml') DO (
SET filename=%~f1 
SET toline=FINDSTR /B /C "To: " 
ECHO %FILENAME%%TOLINE% >> fullnames.txt 
) 

をし、それが動作しません。私がファイル名の行に置いたものに関係なく、エラーや不正確な結果を得ています。ライン部分をテストすることさえも開始していない。助言がありますか?

答えて

0

forループ内で環境変数を割り当てて使用することはできません。遅延変数の拡張を使用するか、サブルーチンを呼び出します。それはとにかく正常に働くだろうように見えないこと、しかしこの

setlocal EnableDelayedExpansion 

    @echo off 
    IF EXIST fullnames.txt DEL fullnames.txt 
    FOR /F %%g IN ('dir /b *.eml') DO (
    SET filename=%~f1 
    SET toline=FINDSTR /B /C "To: " 
    ECHO !FILENAME!!TOLINE! >> fullnames.txt 
    ) 

ようになります遅延

。私はこのようにします

FOR /F %%g IN ('dir /b *.eml') DO call :process %%g 
    goto :eof 

    :process 
    SET filename=%~f1 
    SET toline=FINDSTR /B /C "To: " 
    ECHO %FILENAME%%TOLINE% >> fullnames.txt 
+0

をしかし '設定toline = FINDSTR/B/C「:を」' '_実行_ありませんFINDSTR'コマンドを実行すると、テキストのみが割り当てられます – jeb

2

すでにDIRコマンドの出力をキャプチャするためにFOR/Fを使用しました。 FINDSTRの出力をキャプチャすることも同じです。

ただし、DIRコマンドでFOR/Fの代わりに単純なFORを使用する方が効率的です。

あなたが%%~fgと思ったら、%~f1を使用しました。

%var%を使用してカッコ内の変数セットを展開することはできません。!var!代わりに遅延拡張。詳細については、コマンドラインからSET /?を入力 - で始まるセクションを読んで、「最後に、遅延環境変数の展開のサポートが が追加されました...」

をしかし、あなたのケースでは、あなたが簡単に遅れての使用を避けることができます拡張(それは問題ではない)。

既存の "fullnames.txt"を削除して出力を追加する代わりに、全体の構造をかっこで囲み、すべての出力を上書きモードでファイルにリダイレクトする方が効率的です。

@echo off 
(
    for %%F in (*.eml) do (
    for "delims=" %%A in ('findstr /b /c:"To: " "%%F"') do echo %%F %%A 
) 
) >fullnames.txt 

しかし、上記の解決策は、そのままでは、必要以上に複雑です。

FINDSTRは、ワイルドカードで指定された複数のファイルを処理でき、各一致する行の先頭にファイル名とコロンを付けます。

あなたも、バッチファイルを使用せずに、単純にコマンドラインからあなたの結果を得ることができます(またはバッチファイルでこれを置くことができる):

findstr /b /c:"To: " *.eml >fullnames.txt 

編集
あなたが懸念されている場合は、そのファイルには、複数の行が「TO:」で始まる含まれている可能性があり、そしてあなただけのそれはバッチファイルを使用するように戻って、最初の行を使用したい:

@echo off 
setlocal enableDelayedExpansion 
set "prevFile=" 
(
    for /f "tokens=1* delims=:" %%A in ('findstr /b /c:"To: " *.eml') do (
    if "%%A" neq "!prevFile!" echo %%A: %%B 
    set "prevFile=%%A" 
) 
) >fullnames.txt 

上記の溶液でしFファイル名に!が含まれている場合は不要です。また、パスにドライブ文字が含まれていない限り、パスは*.emlで使用できます。ドライブと!の両方の問題は、追加の変更で解決できます。

2
@echo off 
setlocal EnableDelayedExpansion 
if exist fullnames.txt del fullnames.txt 
for %%f in (*.eml) do (
    set toline= 
    for /F "delims=" %%l in ('findstr /B /C:"To: " "%%f"') do (
     if not defined toline set "toline=%%l" 
    ) 
    echo %%f!toline! >> fullnames.txt 
) 

EDIT簡単な方法は、各ファイルの前に

set toline=コマンド削除「toline」変数を追加し、処理されるので、単に「:を」最初に一致した行が見つかったが、それに割り当てられ、後で遅延拡張を使用して表示されます。しかしdbenhamが示唆したように、このプロセスは、遅延拡張を必要としない簡単な方法で達成することができる。

@echo off 
if exist fullnames.txt del fullnames.txt 
for %%f in (*.eml) do (
    set firstFind= 
    for /F "delims=" %%l in ('findstr /B /C:"To: " "%%f"') do (
     if not defined firstFind set firstFind=now & echo %%f%%l >> fullnames.txt 
    ) 
) 
+0

最初の "To:"行だけを処理しようとすると盗難されます。また、遅延拡張の必要はありません。  内側のループの中で: 'もし定義されていないなら、toline = 1を設定し&echo %% f %% l >> fullnames.txt' – dbenham

+0

@ dbenham:なぜ、第1の" To: " – Aacini

+0

申し訳ありませんAacini、私の部分の愚かな間違い。コードは完全に機能します。 – dbenham

関連する問題