在Windows上与正则表达式匹配的媒体设备上的批量重命名文件

时间:2016-07-04 14:52:29

标签: batch-file

我觉得我可以在使用bash的linux机器上相当容易地做到这一点,但是我没有足够的经验来使用它。

基本上,我手机上的很多音乐文件都以曲目编号开头:

01 - a song
02 - another song
03 a third song (different format)

我可以通过正则表达式匹配轻松获取所有文件:

dir /b | findstr /i "^[0-9]+ .*"

然后我假设我应该将这些值分配给变量。但是我可以通过执行

来执行for循环
for %filename in %var
     ren file [something here]

我遇到的唯一问题是进入媒体设备(Windows如何处理引擎盖?)并删除前缀,同时处理两种可能的格式(检测' - &#39 ;不应该很难)。我可以用sed来做,但我不知道批次的等价物。

1 个答案:

答案 0 :(得分:0)

无论如何,我有意这样做。

Larry Wall多年前写的一个方便的Perl rename script我经常用regexp重命名文件。但是因为我在Windows中很少需要Perl,并且为这个脚本安装Perl似乎是浪费,我一直认为使用本机Windows脚本语言重写prename是一个好主意。

希望如果有任何错误,他们不会太虚弱。我没有对脚本进行过多次测试,但它似乎适用于基本用法,在那里您重命名的文件存在于当前工作目录中。奖励:反向引用适用于替换文本。的Wooo。

使用示例

prename.bat -v "s/searchRXP/replacement/flags" filemask

请在控制台窗口中查看prename.bat -h以获取完整的使用帮助。

prename.bat

<!-- : prename.bat -- http://stackoverflow.com/a/38191137/1683264
@echo off & setlocal

rem // ensure flags and other vars begin undefined
for %%I in (v n f h show filemask search replace flags) do set %%I=

rem // organize arguments
for /f "delims=" %%I in ('cscript //nologo //job:args "%~f0?.wsf" %*') do set "%%~I"
if defined h goto usage
if defined invalid (
    echo Unrecognized option: %invalid%
    goto usage
)
if not defined filemask goto usage
if not defined search goto usage
if defined v set "show=1"
if defined n set "show=1"

rem // expand wildcards
for %%I in (%filemask%) do (
    for /f "delims=" %%# in ('cscript //nologo //job:newname "%~f0?.wsf" "%%~I"') do (
        if defined show echo %%~I -^> %%~#
        if not defined n if not "%%~fI"=="%%~f#" (
            >NUL (
                if defined f (move /y "%%~I" "%%~#") else ren "%%~I" "%%~nx#"
            )
        )
    )
)

goto :EOF

:usage
echo Usage: %~nx0 [-v] [-n] [-f] perlexpr [filelist]
echo    -v shows verbose output
echo    -n performs a simulation only
echo    -f forces overwriting existing files
echo    perlexpr is a Perl-compatible regular expression
echo    filelist can contain wildcards
echo;
echo Example:
echo    %~nx0 -n "s/([^\.]+)$/\1.cmd/i" *.bat
echo This would simulate renaming every .bat file extension to .bat.cmd
goto :EOF

: end batch begin JScript hybrid code -->
<package>
    <job id="args">
        <script language="JScript">
            var args = {
                    v: 0,
                    n: 0,
                    f: 0,
                    h: 0,
                    search: '',
                    replace: '',
                    flags: '',
                    filemask: ''
                };

            for (var i=0; i<WSH.Arguments.length; i++) {
                if (/^[\/-](.)/.test(WSH.Arguments(i))) {
                    if (typeof args[RegExp.$1] === 'undefined')
                        args.invalid = WSH.Arguments(i);
                    args[RegExp.$1] = 1;
                }
                else if (/^s(\W)(.+)\1(.*)\1(.*)/.test(WSH.Arguments(i))) {
                    args.search = RegExp.$2;
                    args.replace = RegExp.$3;
                    args.flags = RegExp.$4;
                }
                else args.filemask += ';' + '"' + WSH.Arguments(i) + '"';
            }
            for (var i in args) if (args[i]) WSH.Echo(i + '=' + args[i]);
        </script>
    </job>
    <job id="newname">
        <script language="JScript">
            var env = WSH.CreateObject('WScript.Shell').Environment('Process'),
                search = env('search'),
                repl = env('replace'),
                flags = env('flags');

            WSH.Echo(WSH.Arguments(0).replace(
                new RegExp(search, flags),
                function(full, $1, $2, $3, $4, $5, $6, $7, $8, $9) {
                    var backref = [full, $1, $2, $3, $4, $5, $6, $7, $8, $9];
                    return repl.replace(
                        /[\\$](\d)/g,
                        function(full, $1) { return backref[$1]; }
                    );
                }
            ));
        </script>
    </job>
</package>