1

私は次のばかげたタスクを達成しようとしています:

完全修飾ファイル名のセットを含むテキスト ファイルがあります。ファイルを反復処理し、各行を共通変数に追加して、コマンド ライン ツールに渡すことができるようにしたいと考えています。たとえば、ファイルは次のようになります。

C:\dir\test.txt

C:\WINDOWS\test2.txt

C:\text3.txt

そして、それらを次のような変数「a」に割り当てたいと思います。

a = "C:\dir\test.txt C:\WINDOWS\test2.txt C:\text2.txt"

2 つ目の質問は、適切なバッチ ファイル リファレンスとは何ですか? Windows の資料や自家製の Web サイトでいくつかの情報を見つけましたが、特に完全なものはありません。

4

4 に答える 4

9

リファレンスに関しては、SS64.comは悪くありません。Rob van der Woudeもかなり頻繁にリンクされます。


あなたの問題に関しては、それは簡単です:

@echo off
setlocal enableextensions enabledelayedexpansion

set LIST=
for /f %%x in (yourfile.txt) do (
    set LIST=!LIST! "%%x"
)

echo %LIST%

endlocal

より詳細な説明:

setlocal enableextensions enabledelayedexpansion

ここでは遅延拡張を有効にしています。forそうしないと、後続のループ内でファイルのリストを操作できなくなるため、これは非常に重要です。

for /f %%x in (yourfile.txt) do (
    set LIST=!LIST! "%%x"
)

for /fファイル内の行を反復処理するため、まさにここで必要なものです。各ループ反復で、次の行をLIST変数に追加します。!LIST!通常の の代わりに を使用していることに注意してください%LIST%。これにより、拡張の遅延が通知され、このコマンドが実行されるたびに変数が再評価されるようになります。

通常cmd、行が読み取られて解析されるとすぐに、変数をその値に展開します。cmd単一の行は、行または行としてカウントされるすべてのもののいずれかです。これは、ここで使用したような括弧で区切られたブロックにも当てはまります。したがってcmd、完全なブロックは、ループの内部が実行される頻度に関係なく、一度読み取られて解析される単一のステートメントです。

%LIST%then の代わりにここで使用した場合!LIST!、変数はすぐにその値 (その時点で空) に置き換えられ、ループは次のようになります。

for /f %%x in (yourfile.txt) do (
    set LIST= "%%x"
)

明らかに、これは私たちが望んでいたものではありません。遅延展開により、その値が本当に必要な場合にのみ変数が展開されるようになります。この場合、ループの内部が実行され、ファイル名のリストが作成されます。

その後、変数%LIST%or !LIST!(どちらを使用するかはもはや重要ではありません) には、ファイルからの行のリストが含まれます。

おかしなことに、setコマンドのヘルプには、遅延展開の例が正確に含まれています。

最後に、遅延環境変数展開のサポートが追加されました。このサポートは、デフォルトでは常に無効になっていますが、CMD.EXE への /V コマンド ライン スイッチを介して有効/無効にすることができます。CMD /? を参照してください。

遅延環境変数展開は、テキスト行が実行されたときではなく、読み取られたときに発生する現在の展開の制限を回避するのに役立ちます。次の例は、即時変数展開の問題を示しています。

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "%VAR%" == "after" @echo If you see this, it worked
)

両方の IF ステートメントの %VAR% は、複合ステートメントである IF の本体を論理的に含むため、最初の IF ステートメントが読み取られるときに置換されるため、メッセージは表示されません。したがって、複合ステートメント内の IF は、実際には「前」と「後」を比較していますが、これは決して等しくなりません。同様に、次の例は期待どおりに動作しません。

set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%

現在のディレクトリにファイルのリストを作成するのではなく、代わりに LIST 変数を最後に見つかったファイルに設定するという点で。繰り返しますが、これは、FOR ステートメントが読み取られるときに %LIST% が 1 回だけ展開され、その時点で LIST 変数が空であるためです。したがって、実行している実際の FOR ループは次のとおりです。

for %i in (*) do set LIST= %i

LIST を最後に見つかったファイルに設定し続けるだけです。

遅延環境変数展開では、別の文字 (感嘆符) を使用して、実行時に環境変数を展開できます。遅延変数展開が有効になっている場合、上記の例は次のように記述して意図したとおりに動作させることができます。

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%
于 2009-09-30T20:53:10.407 に答える
0
type *commonfilepart* >> concat_result_file

OS: Windows Server 2003

于 2010-06-01T13:42:13.447 に答える
0

あなたが求めていることは、FOR /F コマンドで実行できます。

これは、私が何度も使用した優れたリソースです。

http://www.robvanderwoude.com/batchfiles.php

于 2009-09-30T20:53:02.153 に答える
0

良書: Tim Hill 著の Windows NT Shell Scripting。私が持っているエディションは 1998 年に発行されたものですが、Windows 2008 の Windows コマンド プログラムにはまだ有効です。

于 2009-09-30T20:58:08.487 に答える