2

どうすればこれを達成できますか:

for i in *.e; do mv $i ${i%-b*.e}.e; done

Windowsバッチファイルで?(「-b」を含むファイルの名前を「-b」の前の部分に変更します。これは必ずしも文字列の末尾ではないことに注意してください!たとえば、「file-b-4.e」は「file.e」になります)

4

3 に答える 3

5

本当にこれをバッチで実行したい場合は、これが機能するはずです

@echo off
setlocal disableDelayedExpansion
for %%F in (*.e) do (
  set "var=%%~F"
  setlocal enableDelayedExpansion
  set "var=!var:-b=.e:!"
  for /f "eol=: delims=:" %%A in ("!var!") do (
    endlocal
    echo ren "%%F" "%%A"
  )
)

編集
panda-34によるコメントは、ファイル名が。で始まる場合、元の投稿されたコードが失敗したという事実をほのめかしました-b。上記のコードは、拡張機能を置換文字列に組み込むことで修正されました。(問題を警告してくれたpanda-34に感謝します)

panda-34は、検索と置換を伴うコマンドインジェクションを使用する代替ソリューションも提供しました。挿入されたコマンドはREMステートメントです。

&panda-34ソリューションは、ファイル名にまたは文字が含まれていない限り機能しますが、含まれている^場合は失敗します。

以下は、すべての有効なWindowsファイル名で機能するコマンドインジェクション手法の修正バージョンです。2つの重要なmodがあります。1)ファイル名の特殊文字が常に引用符で囲まれていることを確認し、2)値をCALL引数として渡さないようにします。そうしない^と、2倍になり^^ます。

@echo off
setlocal disableDelayedExpansion
for %%i in (*-b*.e) do (
  set old="%%~ni"
  call :ren_b
)
exit /b
:ren_b
set v=%old:-b=.e"&rem "%
echo ren "%old:~1,-1%.e" %v%
exit /b

最終編集(私は願っています):
baruchが彼のコメントで示しているように、上記の解決策は最初の出現から削除しますが、元のbashコマンドは最後の出現から削除します。

以下は、元のbashコマンドとまったく同じバージョンである必要があります。

@echo off
setlocal disableDelayedExpansion
set "search=-b"
for %%A in (*%search%*.e) do (
  set "old=%%A"
  setlocal enableDelayedExpansion
  set "new=\_!old:%search%=\_!"
  for %%B in ("!new!") do (
    endlocal
    set "new=%%~pB"
    setlocal enableDelayedExpansion
    set "new=!new:~2,-1!.e"
    echo ren "!old!" "!new:\_=%search%!"
    endlocal
  )
)
于 2012-05-24T15:44:14.007 に答える
3

シンプルに、本当に

for %%i in (*-b*.e) do call :ren_b %%~ni
goto :eof
:ren_b
set v=%*
set v="%v:-b=.e" ^& rem %
ren "%*.e" %v%

-b最後の出現まで名前を保持するバリアントを次に示します

setlocal enabledelayedexpansion
for %%i in (*-b*.e) do (
    set v=%%~ni
    set v=!v:-b=\!
    for %%j in ("\!v!") do (
        set v=%%~pj
        set v=!v:~1,-1!
        set v=!v:\=-b!
        ren "%%i" "!v!.e"
    )
)

!を含み、で始まる名前では失敗します-b

PS、見ませんでした.dbenhamはすでに同等のソリューションを提供しており、おそらくファイル名の終端ケースに対するより多くの規定があります。

于 2012-05-24T18:01:00.940 に答える
2

忘れてください。NTスクリプトでは便利なことができない場合があります。あなたがここで求めていることは私の知る限り不可能です。そして、私はあらゆる種類のトリックを使用して、50KiBを超える複雑なNTスクリプトを作成および保守しました。「WindowsNTシェルスクリプト」という本は、これらの多くを指摘しています。同じことについては、Rob vanderWoudeのスクリプトページを参照してください。

NTスクリプトで変数拡張がどのように機能するかにより、これの一部を実行できると思いますが、ワンライナーでは実行できません。たとえば、文字列の予想される部分を抽出して、-bそれがそうであるかどうかを確認して-bから、他の部分を抽出し、元の名前から抽出された部分のみで構成される名前に名前を変更できます。

ただし、これを実現するには、おそらく10〜15行必要です。その観点から、目的に応じて別のスクリプト言語を使用することを検討してください。特にこれが最新のWindowsバージョンである場合。

これは望ましい答えではないことを理解しています(つまり、これは可能であり、サンプルです)がcmd.exe、従来のバッチスクリプトの一部の反対者が指摘しているほど制限されていませんが、Bashと比較して非常に制限されています。

于 2012-05-24T14:18:15.720 に答える