バッチファイル内のワイルドカードに一致するファイルをループする方法

StackOverflow https://stackoverflow.com/questions/39615

質問

基本ファイル名のセットがあり、それぞれの名前 'f' に対して、'f.in' と 'f.out' という 2 つのファイルがあります。すべてのファイル名を調べるバッチ ファイル (Windows XP の場合) を作成したいと考えています。それぞれのファイル名について次のようにする必要があります。

  • ベース名「f」を表示します
  • 「f.in」でアクションを実行します
  • 「f.out」で別のアクションを実行します

たとえば *.in (または *.out) を検索する以外に、ベース ファイル名のセットをリストする方法はありません。

役に立ちましたか?

解決

process_in.exe と process_out.exe という 2 つのファイルを処理する 2 つのプログラムがあると仮定します。

for %%f in (*.in) do (
    echo %%~nf
    process_in "%%~nf.in"
    process_out "%%~nf.out"
)

%%~nf は置換修飾子で、%f をファイル名のみに展開します。他の修飾子を参照してください。 https://technet.microsoft.com/en-us/library/bb490909.aspx (ページの途中)または次の回答にあります。

他のヒント

この行を使用して、デスクトップの内容を印刷できます。

FOR %%I in (C:\windows\desktop\*.*) DO echo %%I 

入手したら、 %%I 変数に対してコマンドを実行するのは簡単です (単語 echo をプログラムに置き換えるだけです)

さらに、可変参照の置換が強化されました。次のオプションの構文を使用できるようになりました。

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only (directory with \)
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string


[https://ss64.com/nt/syntax-args.html][1]

上記の例では %I パスは他の有効な値に置き換えることができます。の %~ 構文は有効な FOR 変数名で終了します。次のような大文字の変数名を選択します %I それをより読みやすくし、修飾子との混乱を回避しますが、これはケースに敏感ではありません。

次のように入力すると、完全なドキュメントを入手できます。 FOR /?

私が考える最も簡単な方法は、処理のために 2 番目のバッチ ファイルを呼び出し、その 2 番目のファイルにベース名を渡す for ループを使用することです。

によると/?help、basename は気の利いた ~n オプションを使用して抽出できます。したがって、基本スクリプトは次のようになります。

for %%f in (*.in) do call process.cmd %%~nf

次に、process.cmd では、%0 にベース名が含まれていると想定し、それに応じて動作します。例えば:

echo The file is %0
copy %0.in %0.out
ren %0.out monkeys_are_cool.txt

これを 1 つのスクリプトで実行するより良い方法があるかもしれませんが、バッチ ファイルの 1 つの for ループで複数のコマンドを取得する方法については、私は常に少し曖昧でした。

編集:素晴らしいですね!FOR ループで複数行のブロックを実行できることを示すドキュメントのページをどういうわけか見逃していました。今から戻っていくつかのバッチ ファイルを書き直す必要があります...

(私が覚えている限りでは) MS サーバーで通常使用されるツールがあります。 フォファイル:

上記のリンクには、ヘルプと Microsoft ダウンロード ページへのリンクが含まれています。

拡張する ネイサンズ 役職。以下は 1 つのバッチ ファイルでジョブ ロットを実行します。

@echo off

if %1.==Sub. goto %2

for %%f in (*.in) do call %0 Sub action %%~nf
goto end

:action
echo The file is %3
copy %3.in %3.out
ren %3.out monkeys_are_cool.txt

:end

以下のコードは、指定された部分文字列で始まるファイル名をフィルターします。subfname の部分文字列抽出と IF ステートメントを操作することで、さまざまなニーズに合わせて変更できます。

echo off
rem filter all files not starting with the prefix 'dat'
setlocal enabledelayedexpansion
FOR /R your-folder-fullpath %%F IN (*.*) DO (
set fname=%%~nF
set subfname=!fname:~0,3!
IF NOT "!subfname!" == "dat" echo "%%F"
)
pause

f.in と f.out をエコーすると、for /f ループで使用するときに、何をループするか、何をループしないかの概念が分離されます。

::Get the files seperated
echo f.in>files_to_pass_through.txt
echo f.out>>files_to_pass_through.txt

for /F %%a in (files_to_pass_through.txt) do (
for /R %%b in (*.*) do (
if "%%a" NEQ "%%b" (
echo %%b>>dont_pass_through_these.txt
)
)
)
::I'm assuming the base name is the whole string "f".
::If I'm right then all the files begin with "f".
::So all you have to do is display "f". right?
::But that would be too easy.
::Let's do this the right way.
for /f %%C in (dont_pass_through_these.txt)
::displays the filename and not the extention
echo %~nC
)

質問されていませんが、コマンドを f.in と f.out に渡す良い方法は次のとおりです...

for /F %%D "tokens=*" in (dont_pass_through_these.txt) do (
for /F %%E in (%%D) do (
start /wait %%E
)
)

すべての Windows XP コマンドへのリンク:リンク

正しく答えていなかったら申し訳ありません。その質問は私にとって非常に読みにくかったです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top