バッチ:ファイル拡張子を削除


155

私はウィキペディアから次のバッチスクリプトを持っています:

@echo off
    for /R "C:\Users\Admin\Ordner" %%f in (*.flv) do (
    echo %%f
)
pause

forループでは、拡張子flvのすべてのファイルがエコーされますが、拡張子なしのファイルと拡張子付きのファイルを1回ずつ必要とするファイルに対していくつかのアクションを実行します。どうすればこれら2つを入手できますか?

解決策を検索しましたが、見つかりません。私はバッチの本当の初心者です...

回答:


309

%%~nfのリファレンスで説明されているようにのみ、を使用してファイル名を取得できますfor

@echo off
    for /R "C:\Users\Admin\Ordner" %%f in (*.flv) do (
    echo %%~nf
)
pause

次のオプションを使用できます。

修飾子付きの変数説明

%〜Iは%Iを展開し、周囲をすべて削除します 
                        引用符( "")。
%〜fI%Iを完全修飾パス名に展開します。
%〜dI%Iをドライブ文字のみに展開します。
%〜pI%Iをパスのみに展開します。
%〜nI%Iをファイル名のみに展開します。
%〜xI%Iをファイル拡張子のみに展開します。
%〜sI短い名前のみを含むようにパスを拡張します。
%〜aI%Iをfileのファイル属性に展開します。
%〜tI%Iをファイルの日付と時刻に展開します。
%〜zI%Iをファイルのサイズに拡張します。
%〜$ PATH:I PATH環境にリストされているディレクトリを検索します 
                        変数と%Iを完全修飾名に展開します 
                        最初に見つかったもの。環境変数名が
                        定義されていないか、ファイルが検索で見つかりません、
                        この修飾子は空の文字列に展開されます。    

8
簡単なメモ:上記の例では、%% fは次のようにC:\Users\Admin\Ordner\foo.flvなり、%%〜nfが表示されますfoo。拡張機能以外のすべてが必要な場合は、%%C:\Users\Admin\Ordner\foo
〜df

8
@ehambright遅いコメントです%%~dpnfが、使用する方が短い選択肢になると思います。

修飾子/説明表Dirkをありがとう。私の場合は%1、バッチスクリプトでparamから拡張子なしのファイル名を取得していました。echo %~n1私が求めていたものでした。
Dave Pile

26

変数が保持するファイルが実際に存在しない場合、FORアプローチは機能しません。拡張子の長さがわかっている場合に使用できるトリックの1つは、部分文字列を取ることです。

%var:~0,-4%

-4最後の4桁の数字(おそらくことを意味.EXTが)切り捨てられます。


これは私にとっては機能しません(Win8.1の場合)- echo %f:~0,-4%質問で使用されている例のコンテキストで試した場合、誤解している可能性があります。何が悪いのですか?
ウルフ

2
どうやら、これはFOR変数ではなく「通常の」変数で機能します(または、おそらく正しい構文がわからないだけかもしれません)。とにかく、これはOPの例のコンテキストで機能します。SET fl=%%fそれからecho %fl:~0,-4%
Ohad Schneider、

@Wolfループ変数の値を通常の変数に設定し、通常の変数で文字列の置換/切り捨てを行う必要があります
phuclv

十分な場合を超えて、延長の長さが3に等しくないか、不明です。ファイルが存在しない場合でも、forを使用できます。私の回答を参照してください。
marsze


8

これは本当に遅い応答ですが、私はDiskInternals LinuxReaderが非NTFS(FAT32)ディレクトリに保存したファイルに '.efs_ntfs'を追加していた特定の問題を解決するためにこれを思いつきました:

@echo off
REM %1 is the directory to recurse through and %2 is the file extension to remove
for /R "%1" %%f in (*.%2) do (
    REM Path (sans drive) is given by %%~pf ; drive is given by %%~df
    REM file name (sans ext) is given by %%~nf ; to 'rename' files, move them
    copy "%%~df%%~pf%%~nf.%2" "%%~df%%~pf%%~nf"
    echo "%%~df%%~pf%%~nf.%2" copied to "%%~df%%~pf%%~nf"
echo.
)
pause

質問の答えはわかりませんが、実際に役に立ちました。ありがとうございます。
matan7890 2014

1
@ matan7890 True; opは、「ファイルでいくつかのアクションを実行したい」[sic]が必要とするものを指定していませんが、それらのアクションの1つがそれらの名前を変更している場合があります。その場合、私の答えは受け入れられた答えの拡張です。
Agi Hammerthief 2014

これは、.encrypted身代金要求とともに、添付ファイルを開いてすべてのファイルに追加した私の友人を助けました。攻撃スクリプトは、これとは逆のバッチファイルであり、.encryptedすべてのファイルに追加されているようです。
AwokeKnowing 2016年

1
ドライブ、パス、および拡張子(%%〜df %%〜pf %%〜nf)に言及しているため、賛成票を投じました。これは、拡張子なしのファイル名(%% だけではなく、元の質問からの%% fの出力に最もよく似ています)〜NF
ehambright

5

(ディレクトリや既存のファイルをループせずに)変数から拡張子を削除するだけの場合は、これを使用しています。

for %%f in ("%filename%") do set filename=%%~nf

完全なパスから拡張機能を削除する場合は、%%dpnf代わりに次を使用します。

for %%f in ("%path%") do set path=%%~dpnf

例:

(コンソールで直接使用)

@for %f in ("file name.dat") do @echo %~nf
@for %f in ("C:\Dir\file.dat") do @echo %~dpnf

OUTPUT:

file name
C:\Dir\file

0

cygwin bashを使用してチョッピングを行う

  :: e.g. FILE=basename.mp4 => FILE_NO_EXT=basename
  set FILE=%1
  for /f "delims=" %%a in ('bash -c "FILE=%FILE%; echo ${FILE/.*/}" ') do set FILE_NO_EXT=%%a

0

変数が引数の場合は%~dpn、引数番号を続けて使用するだけでよいので、拡張子の長さを変えることを心配する必要はありません。

たとえば%~dpn0、拡張子なしでバッチファイルのパスを返す、拡張子なしなどに%~dpn1なります%1

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