バッチファイルで部分文字列を作成する最良の方法は何ですか?


192

現在実行中のバッチファイルの名前をファイル拡張子なしで取得したいのですが。

おかげこのリンクは、私は、ファイル名を持っている拡張...しかし、バッチファイルでストリングを行うための最善の方法は何ですか?

または、拡張子なしでファイル名を取得する別の方法はありますか?

このシナリオでは、3文字の拡張子を想定しても安全です。

回答:


395

まあ、バッチのファイル名を取得するための最も簡単な方法は、を使用すること%~n0です。

@echo %~n0

現在実行中のバッチファイルの名前(拡張子なし)を出力します(によって呼び出されたサブルーチンで実行された場合を除くcall)。パス名のそのような「特別な」置換の完全なリストhelp forは、ヘルプの最後にあるで確認できます。

さらに、FOR変数参照の置換が強化されました。これで、次のオプションの構文を使用できます。

%~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
%~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

修飾子を組み合わせて複合結果を得ることができます。

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only

ただし、質問に正確に回答するには、次の:~start,length表記を使用して部分文字列を作成します。

%var:~10,5%

環境変数の位置10から5文字を抽出します%var%

注:文字列のインデックスはゼロベースなので、最初の文字は位置0にあり、2番目は1にあります。

以下のような引数変数の部分文字列を取得するには%0%1などあなたは、通常の環境変数を使用してそれらを割り当てる必要がset最初:

:: Does not work:
@echo %1:~10,5

:: Assign argument to local variable first:
set var=%1
@echo %var:~10,5%

構文はさらに強力です:

  • %var:~-7% から最後の7文字を抽出します %var%
  • %var:~0,-4%最後の4文字を除くすべての文字を抽出します。これにより、ファイル拡張子も削除されます(ピリオド[ .]の後の3文字を想定)。

help setその構文の詳細については、を参照してください。


31
部分文字列抽出はFORループ変数でも機能しないため、次のようにする必要があります(コード内の\ r \ nは、コメント内で改行が許可されていないため、改行を意味します):setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
Fr0sT

@ Fr0sTなぜFORループのためにこれをしなければならないのですか?
Bob

4
@エイドリアンはなぜですか?FORは、非常に多数のさまざまなタスクを実行するバッチファイルの基礎となる構造です。ところで、すなわち、サブルーチンを使用してタスクに対処するもう一つの方法がありますfor /f %%s in ('set') do call :DoSmth "%%s" \r\n ... \r\n :DoSmth \r\n set var=%1 \r\n echo %var:~1,3%
Fr0sT

1
Windows Server 12 R2を使用すると、%date%は21/05/18(ITカルチャ)のようになります。右側の文字列は次のとおりです。 %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01

@ Phate01、%date%特定の形式で日付を作成するために使用しないでください。形式はユーザーの文化に固有であり、変更される可能性があります。代わりにWMIを使用して、ユーザーの設定に依存しない便利な形式で日付と時刻を取得します。また、この質問は日付や時間に関するものではなかったため、このコメントがここで何をしているのかわかりません。
ジョーイ

38

上でうまく説明しました!

ローカライズされたWindows(私のものはスロバキア語のXP)でこれを機能させるのが私のように苦しむ可能性があるすべての人にとって%、を!

そう:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!

27
これはsetlocal ENABLEDELAYEDEXPANSIONコマンドの後でのみ機能することに注意してください
Fr0sT

13

Joeyの回答への追加情報として、のヘルプには記載されていset /?ませんfor /?

%~0入力したとおりに、独自のバッチの名前に展開されます。
したがって、バッチを開始すると、次のように展開されます

%~0   - mYbAtCh
%~n0  - mybatch
%~nx0 - mybatch.bat

ただし、例外が1つあります。サブルーチンでの展開は失敗する可能性があります。

echo main- %~0
call :myFunction
exit /b

:myFunction
echo func - %~0
echo func - %~n0
exit /b

これは

main - myBatch
Func - :myFunction
func - mybatch

関数で%~0は常に、バッチファイルではなく関数の名前に展開されます。
ただし、少なくとも1つの修飾子を使用すると、ファイル名が再び表示されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.