2011-06-29 3 views
2

バッチスクリプトの単調なファイルリネーマーを作成しています。基本的には、すべてのファイルのタイトルを1 2 3 4 ....とします。私はそれ以来、さまざまなタイプのファイル(txt、doc、flvなど)を扱えるように拡張しましたが、すべてがうまくいきません。ファイルの名前を変更するバッチスクリプトの有効な拡張で問題が発生する

私の主な関心事は、私が以前作っていた遅延拡張コールを壊してしまったことです。今は!var1を使って!展開されたり、変数として認識されることはありません。ここ

は、アイデアは私が私の中に2つのファイルrenamer.bat(このファイル)とexttostr.bat(ファイルの拡張子を取得するためのヘルパーを)落としている私のスクリプトの冗長にコメントしたバージョン

::a monotonic file renamer 
@echo off 
SETLOCAL ENABLEDELAYEDEXPANSION 

SET tempfile=temp.txt 
SET exttemp=exttemp.txt 
if [%1] == [] goto usage 

::make sure your dont overwrite something useful 
if EXIST %tempfile% (
ECHO Temp file already exists, are you sure you want to delete? 
del /P %tempfile% 
) 
if EXIST %exttemp% (
ECHO EXT Temp file already exists, are you sure you want to delete? 
del /P %exttemp% 
) 

::initialize 
SET /a counter=0 
SET type= 
SET /a ender=%1 

::write filenames to tempfile 
DIR /B /ON > %tempfile% 

::read lines one by one 
for /f "usebackq delims=" %%a in (%tempfile%) do (
REM make sure we do not rename any of the working files 
if NOT "%%a"=="renamer.bat" (
if NOT "%%a"=="temp.txt" (
if NOT "%%a"=="exttostr.bat" (
SET /a counter+=1 
REM get file extension 
exttostr %%a > %exttemp% 
SET /P type= < %exttemp% 
REM housekeeping 
del /F %exttemp% 
REM rename 
ren %%a !counter!.!type! 
ECHO Renamed "%%a" to "!counter!.!type!" 
))) 
REM exit when we have run enough 
if "!counter!"=="!ender!" goto exit 
) 

goto exit 

:usage 
echo Usage: renamer NUMFILES 

:exit 
::final housekeeping 
DEL temp.txt 

ですそれを実行すると、1からアルファベット順にソートされたファイルの名前が、指定したファイルの名前に変更されます。

私はコードを実行するときに遅延拡張のマークが付いた変数を使用することはありません。常に "!varname!"のままにしておけば、最初のファイル "!counter!。!type!"その名前のディレクトリにすでにファイルがあるため、残りの部分にエラーがスローされます。

これは私に副次的な問題をもたらします。アルファベット順にディレクトリリストをソートすると、番号付きファイルの処理が悪くなります。 "1 7 15 75 120" はソートされました: "1 120 15 7 75" 私はこれを回避する方法を見つけることができませんでしたが、これは本当にディレクトリの意図した結果であるソート。私が持っている唯一の回避策は、前面に十分な数の数字を埋めていることです。

事前の感謝のおかげで!


すべてがソートされていますが、2番目の問題です。私はよく話さなかったと思う。私はこの問題を、ディレクトリファイル名を取り込むときに書いています。彼らはすでにパッドが必要です。私はディレクトリを読んでそれを適切にソートする他の方法があることを望んでいました。

、私が発見した最も有望なものはここにある:http://www.dostips.com/DtCodeBatchFiles.php#Batch.SortTextWithNumbers

@ECHO OFF 
if "%~1"=="/?" (
    echo.Sorts text by handling first number in line as number not text 
    echo. 
    echo.%~n0 [n] 
    echo. 
    echo. n  Specifies the character number, n, to 
    echo.  begin each comparison. 3 indicates that 
    echo.  each comparison should begin at the 3rd 
    echo.  character in each line. Lines with fewer 
    echo.  than n characters collate before other lines. 
    echo.  By default comparisons start at the first 
    echo.  character in each line. 
    echo. 
    echo.Description: 
    echo.  'abc10def3' is bigger than 'abc9def4' because 
    echo.  first number in first string is 10 
    echo.  first number in second string is 9 
    echo.  whereas normal text compare returns 
    echo.  'abc10def3' smaller than 'abc9def4' 
    echo. 
    echo.Example: 
    echo.  To sort a directory pipe the output of the dir 
    echo.  command into %~n0 like this: 
    echo.   dir /b^|%~n0 
    echo. 
    echo.Source: http://www.dostips.com 
    goto:EOF 
) 

if "%~1" NEQ "~" (
    for /f "tokens=1,* delims=," %%a in ('"%~f0 ~ %*|sort"') do echo.%%b 
    goto:EOF 
) 
SETLOCAL ENABLEDELAYEDEXPANSION 
set /a n=%~2+0 
for /f "tokens=1,* delims=]" %%A in ('"find /n /v """') do (
    set f=,%%B 
    (
     set f0=!f:~0,%n%! 
     set f0=!f0:~1! 
     rem call call set f=,%%%%f:*%%f0%%=%%%%  
     set f=,!f:~%n%! 
    ) 
    for /f "delims=1234567890" %%b in ("!f!") do (
     set f1=%%b 
     set f1=!f1:~1! 
     call set f=0%%f:*%%b=%% 
    ) 
    for /f "delims=abcdefghijklmnopqrstuwwxyzABCDEFGHIJKLMNOPQRSTUWWXYZ~`@#$*_-+=:;',.?/\ " %%b in ("!f!") do (
     set f2=00000000000000000000%%b 
     set f2=!f2:~-20! 
     call set f=%%f:*%%b=%% 
    ) 
    echo.!f1!!f2!!f!,%%B 
    rem echo.-!f0!*!f1!*!f2!*!f!*%%a>&2 
) 

このコードはそれらに1つの番号を含むファイル名をソートすることができます(つまりvideo100.movは結構です、video100video10.movはそれを破るだろう)

私が持っている問題は、このヘルパーfnの呼び出しを追加することでもう一度それを破ると思うので、私はこれを私の修正されたrenamer.batに含めるようにしようと考えています。どんな助けもありがとう。

+0

'exttostr'はバッチファイルなので、それを呼び出すために' call'が必要です。そうでなければ、あなたのスクリプトはそこで停止します。 – jeb

+0

ありがとうございます、 "コール"は動作します。もし誰かが私がコードを追加するのを助けることができれば、それは完璧だろう。私は1つのファイルが必要です! :-)助けてくれてありがとう、そしてすでに私を助けてくれた人に感謝します。 – walrus

答えて

3

エクステンションを抽出するためのバッチは、おそらくローカル環境をリセットします。

しかし、あなたはそれを必要としません。拡張子は~xオプションで抽出できます。これと似たような....

:monotonicrename 
set /a counter = 0 
for %%a in (%1\*.*) do (
    if exist %%~fa (
    set /a counter += 1 
    echo ren %%~fa !counter!%%~xa 
) 
) 
goto :eof 

三行

set zcounter=0000!counter! 
set zcounter=!zcounter:~-4! 
echo ren %%~fa !counter!%%~xa 

で、前のrenameコマンドを置き換え、正しくなるようにディレクトリの種類、カウンターで先行ゼロを含めるので、一緒にすべてのピースを置きますバッチファイルで作成したmonotonicrename関数を追加すると、よりシンプルになります...

@echo off 
setlocal enabledelayedexpansion 
call :monotonicrename %1 
goto :eof 
:monotonicrename 
set /a counter = 0 
for %%a in (%1\*.*) do (
    if exist %%~fa (
    set /a counter += 1 
    set zcounter=0000!counter! 
    set zcounter=!zcounter:~-4! 
    echo ren %%~fa !zcounter!%%~xa 
) 
) 
goto :eof 
+0

元の機能の一部を破棄しました。名前変更の数(スクリプトの最初のパラメータ)の制限です。他の点では、私のように 'IN(\' DIR \ ')'の代わりに 'IN(*。*)'を使うのは良い考えです。 –

+0

私の目標はOPの場合の完全な解決策を提供していませんでした。OPの問題を解決する方法を示すには、先行ゼロのカウンタで名前を変更し、拡張子を残してください。 –

1

私は遅れ拡大に伴うすべての問題を経験していない、すべてが(もちろん、私はexttostr.batヘルパースクリプトを持っていなかったという事実を除く。)私のためにうまく働いとにかく

  1. あなたが後でそれを読むためにファイルにDIRの結果を保存する必要はありません:あなたのスクリプトについて改善される可能性がいくつかあります。出力はFORループで直接読むことができます。

  2. ヘルパーバッチスクリプトは不要です。拡張子は%%aから、~x修飾子とループ変数:%%~xaを使用して抽出できます。修飾子の詳細については、コマンドプロンプトからHELP FORを発行して読むことができます。

  3. リネマバッチファイル自体の名前は、スクリプト内で%0として参照できます。 ~n修飾子は、拡張子を付けずに名前を使用する必要がある場合にのみ適用できます。 ~nxを組み合わせると、拡張子の付いた名前が表示されます。

だから、ここスクリプトは上記の問題を持つように見えるかもしれない方法ですが対処:

あなたの二次の問題については
::a monotonic file renamer 
@echo off 
SETLOCAL ENABLEDELAYEDEXPANSION 

IF [%1] == [] GOTO usage 

::initialize 
SET /A counter=0 
SET type= 
SET /A ender=%1 

::read lines one by one 
FOR /F "usebackq delims=" %%a IN (`DIR /B /ON`) DO (
    REM make sure we do not rename any of the working files 
    IF NOT "%%~a"=="%~nx0" (
    SET /A counter+=1 
    RENAME "%%~a" "!counter!%%~xa" 
    ECHO Renamed "%%~a" to "!counter!%%~xa" 
) 
    REM exit when we have run enough 
    IF "!counter!"=="!ender!" GOTO :EOF 
) 

GOTO :EOF 

:usage 
ECHO Usage: %~n0 NUMFILES 

が、それは簡単にこのように解決することができます。

  1. 100000のようなものをcounterの初期値として使用してください。 (好きな数は0にしてください。でも、9を超えないようにしてください)。enderにも同じ値を加えてください。

  2. ファイルの名前を変更するのではなく、!counter!最初の文字(1)を削除し表現を使用します。!counter:~1!(実際には、これは除去に関するものではありませんが、1のオフセットから始まる部分文字列を抽出することについて、詳細をそれについてHELP SETコマンドで)。あなたはまた、私は、ファイル名を二重引用符で囲まれ、代わりにGOTO :EOFを使用していることを確認することと同様に、他のいくつかの機能強化を行っていることがわかります

    ::a monotonic file renamer 
    @echo off 
    SETLOCAL ENABLEDELAYEDEXPANSION 
    
    IF [%1] == [] GOTO usage 
    
    ::initialize 
    SET /A counter=1000 
    SET type= 
    SET /A ender=%1 
    SET /A ender+=counter 
    
    ::read lines one by one 
    FOR /F "usebackq delims=" %%a IN (`DIR /B /ON`) DO (
        REM make sure we do not rename any of the working files 
        IF NOT "%%~a"=="%~nx0" (
        SET /A counter+=1 
        RENAME "%%~a" "!counter:~1!%%~xa" 
        ECHO Renamed "%%~a" to "!counter:~1!%%~xa" 
    ) 
        REM exit when we have run enough 
        IF "!counter!"=="!ender!" GOTO :EOF 
    ) 
    
    GOTO :EOF 
    
    :usage 
    ECHO Usage: renamer NUMFILES 
    

    :ここ

は、上記のスクリプトの修正版です GOTO exit:EOFは、バッチスクリプトの最後を指す特別な事前定義ラベルなので、自分で定義する必要はありません)。

関連する問題