重命名文件的脚本

发布于 2024-12-25 22:51:10 字数 359 浏览 1 评论 0原文

我在几个不同的文件夹中有大约 2200 个不同的文件,我需要重命名其中大约 1/3 的文件,这些文件位于它们自己的子文件夹中。这 700 个也位于不同的文件夹中。

例如,可能有 最顶层的文件夹是Employees,其中有一些文件,然后文件夹2002有一些文件,2003有更多文件,2004等。

我只需在每个文件的现有名称之前附加“协议”一词即可。因此,它不再只是“Joe Schmoe.doc”,而是“Agreement Joe Schmoe.doc”。

我试过用谷歌搜索这样的脚本,我可以找到与我想要的类似的东西,但它对我来说看起来完全陌生,所以我不明白如何修改它以满足我的需要。

哦,这是针对 Windows Server '03 的。

I have about 2200 different files in a few different folders, and I need to rename about about 1/3 of them which are in their own subfolder. Those 700 are also in various folders as well.

For example, there might be
The top-most folder is Employees, which has a few files in it, then the folder 2002 has a few, 2003 has more files, 2004 etc.

I just need to attach the word "Agreement" before the existing name of each file. So instead of it just being "Joe Schmoe.doc" It would be "Agreement Joe Schmoe.doc" instead.

I've tried googling such scripts, and I can find stuff similar to what I want but it all looks completely foreign to me so I can't understand how I'd modify it to suit my needs.

Oh, and this is for windows server '03.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相守太难 2025-01-01 22:51:10

我需要大约 2 分钟为 *NIX 系统编写这样的脚本(可能更少),但对于 Windows 来说这是一首很长的歌...))

我已经为 WSH 编写了简单的 VBS 脚本,尝试一下(保存到 {script- name}.vbs,更改路径值(在脚本的第一行)并执行)。我建议第一次在少量数据上测试脚本,以确保它是否正常工作。

Path = "C:\Users\rootDirectory"
Set FSO = CreateObject("Scripting.FileSystemObject")

Sub visitFolder(folderVar)
    For Each fileToRename In folderVar.Files
        fileToRename.Name = "Agreement " & fileToRename.Name
    Next
    For Each folderToVisit In folderVar.SubFolders
        visitFolder(folderToVisit)
    Next
End Sub

If FSO.FolderExists(Path) Then
    visitFolder(FSO.getFolder(Path))
End If

I need about 2 minutes to write such script for *NIX systems (may be less), but for Windows it is a long song ... ))

I've write simple VBS script for WSH, try it (save to {script-name}.vbs, change Path value (on the first line of the script) and execute). I recommend to test script on small amount of data for the first time just to be sure if it works correctly.

Path = "C:\Users\rootDirectory"
Set FSO = CreateObject("Scripting.FileSystemObject")

Sub visitFolder(folderVar)
    For Each fileToRename In folderVar.Files
        fileToRename.Name = "Agreement " & fileToRename.Name
    Next
    For Each folderToVisit In folderVar.SubFolders
        visitFolder(folderToVisit)
    Next
End Sub

If FSO.FolderExists(Path) Then
    visitFolder(FSO.getFolder(Path))
End If
烛影斜 2025-01-01 22:51:10

我曾经在 Windows 下使用批处理脚本进行批量重命名。我知道这是 *nix 上的一个快照(find .-maxdepth N -type f -name "$pattern" | sed -e 'p' -e "s/$str1/$str2/g" | xargs -n2 mv)。经过一番徒劳的挣扎后,我发现,使用批处理脚本来达到这种效果几乎是不可能的。所以我转向了javascript。

使用此脚本,您可以通过 'rename.js "s/^/Agreement /" -r *.doc' 在文件名中添加前缀。插入符号(^) 表示匹配开头。 “-r”选项表示“递归”,即包括子文件夹。您可以使用“-d N”选项指定最大深度。如果未给出“-r”或“-d N”,则脚本不会递归。

如果您了解 *nix 'find' 实用程序,您会注意到 'find' 会将完整路径(而不仅仅是文件名部分)与指定的正则表达式相匹配。此行为可以通过提供“-f”选项来实现。默认情况下,此脚本将文件名部分与给定的正则表达式进行匹配。

如果您熟悉正则表达式,则可以进行复杂的重命名。例如,'rename.js "s/(\d+)/[$1]/" *' 使用分组将括号添加到文件名中的数字序列。

// rename.js --- bulk file renaming utility (like *nix rename.pl)
// (c) Copyright 2012, Ji Han (hanji <at> outlook <dot> com)
// you are free to distribute it under the BSD license.

// oops... jscript doesn't have array.map
Array.prototype.map = function(f, t){
    var o = Object(this);
    var a = new Array(o.length >>> 0);
    for (var i = 0; i < a.length; ++i){ if (i in o) a[i] = f.call(t, o[i], i, o) }
    return a;
};

/// main
(function(){

if (WScript.Arguments.Length == 0){
    WScript.Echo('rename "<operator>/<pattern>/<string>/[<modifiers>]" [-f] [-r] [-d <maxdepth>] [<files>]');
    WScript.Quit(1);
}

var fso = new ActiveXObject('Scripting.FileSystemObject');

// folder is a Folder object [e.g. from fso.GetFolder()]
// fn is a function which operates on File/Folder object
var recurseFolder = function(folder, fn, depth, maxdepth){
    if (folder.Files){
        for (var e = new Enumerator(folder.Files); !e.atEnd(); e.moveNext()){
            fn(e.item())
        }
    }
    if (folder.Subfolders){
        for (var e = new Enumerator(folder.SubFolders); !e.atEnd(); e.moveNext()){
            fn(e.item());
            if (depth < maxdepth){ arguments.callee(e.item(), fn, depth + 1, maxdepth) }
        }
    }
}

// expand wildcards (asterisk [*] and question mark [?]) recursively
// given path may be relative, and may contain environment variables.
// but wildcards only work for the filename part of a path.
// return an array of full paths of matched files.
// {{{
var expandWildcardsRecursively = function(n, md){
    var pattern = fso.GetFileName(n);
    // escape regex metacharacters (except  \, /, * and ?)
    // \ and / wouldn't appear in filename
    // * and ? are treated as wildcards
    pattern = pattern.replace(/([\[\](){}^$.+|-])/g, '\\$1');
    pattern = pattern.replace(/\*/g, '.*');  // * matches zero or more characters
    pattern = pattern.replace(/\?/g, '.');  // ? matches one character
    pattern = pattern.replace(/^(.*)$/, '\^$1\
);  // matches the whole filename
    var re = new RegExp(pattern, 'i');  // case insensitive
    var folder = fso.GetFolder(fso.GetParentFolderName(fso.GetAbsolutePathName(n)));
    var l = [];
    recurseFolder(folder, function(i){ if (i.Name.match(re)) l.push(i.Path) }, 0, md);
    return l;
}
// }}}

// parse "<operator>/<pattern>/<string>/[<modifiers>]"
// return an array splitted at unescaped forward slashes
// {{{
var parseExpr = function(s){
    // javascript regex doesn't have lookbehind...
    // reverse the string and lookahead to parse unescaped forward slashes.
    var z = s.split('').reverse().join('');

    // match unescaped forward slashes and get their positions.
    var re = /\/(\\\\)*(?!\\)/g;
    var l = [];
    while (m = re.exec(z)){ l.push(m.index) }

    // split s at unescaped forward slashes.
    var b = [0].concat(l.map(function(x){ return s.length - x }).reverse());
    var e = (l.map(function(x){ return s.length - x - 1 }).reverse()).concat([s.length]);
    return b.map(function(_, i){ return s.substring(b[i], e[i]) });
}
// }}}

var expr = WScript.Arguments(0);
var args = [];
var options = {};

for (var i = 1; i < WScript.Arguments.Length; ++i){
    if (WScript.Arguments(i).substring(0, 1) != '-'){
        args.push(WScript.Arguments(i));
    } else if (WScript.Arguments(i) == '-f'){
        options['fullpath'] = true;
    } else if (WScript.Arguments(i) == '-r'){
        options['recursive'] = true;
    } else if (WScript.Arguments(i) == '-d'){
        options['maxdepth'] = WScript.Arguments(++i);
    } else if (WScript.Arguments(i) == '--'){
        continue;
    } else {
        WScript.Echo('invalid option \'' + WScript.Arguments(i) +'\'');
        WScript.Quit(1);
    }
}

if (options['maxdepth']){
    var md = options['maxdepth'];
} else if (options['recursive']){
    var md = 1<<31>>>0;
} else {
    var md = 0;
}

var tokens = parseExpr(expr);
if (tokens.length != 4){
    WScript.Echo('error parsing expression \'' + expr + '\'.');
    WScript.Quit(1);
}
if (tokens[0] != 's'){
    WScript.Echo('<operator> must be s.');
    WScript.Quit(1);
}

var pattern = tokens[1];
var substr = tokens[2];
var modifiers = tokens[3];
var re = new RegExp(pattern, modifiers);

for (var i = 0; i < args.length; ++i){
    var l = expandWildcardsRecursively(args[i], md);
    for (var j = 0; j < l.length; ++j){
        var original = l[j];
        if (options['fullpath']){
            var nouveau = original.replace(re, substr);
        } else {
            var nouveau = fso.GetParentFolderName(original) + '\\' + fso.GetFileName(original).replace(re, substr);
        }
        if (nouveau != original){
            (fso.FileExists(original) && fso.GetFile(original) || fso.GetFolder(original)).Move(nouveau)
        }
    }
}

})();

I used to do bulk renaming with batch scripts under Windows. I know it's a snap on *nix (find . -maxdepth N -type f -name "$pattern" | sed -e 'p' -e "s/$str1/$str2/g" | xargs -n2 mv). Buf after some struggle in vain, I found out, to achieve that effect using batch scripts is almost impossible. So I turned to javascript.

With this script, you can add prefix to file names by 'rename.js "s/^/Agreement /" -r *.doc'. A caret(^) means to match the beginning. The '-r' options means 'recursively', i.e. including sub-folders. You can specify a max depth with the '-d N' option. If neither '-r' or '-d N' is given, the script does not recurse.

If you know the *nix 'find' utility, you would notice that 'find' will match the full path (not just the file name part) to specified regular expression. This behavior can be achieved by supplying the '-f' option. By default, this script will match the file name part with the given regular expression.

If you are familiar with regular expressions, complicated renaming is possible. For example, 'rename.js "s/(\d+)/[$1]/" *' which uses grouping to add brackets to number sequences in filenames.

// rename.js --- bulk file renaming utility (like *nix rename.pl)
// (c) Copyright 2012, Ji Han (hanji <at> outlook <dot> com)
// you are free to distribute it under the BSD license.

// oops... jscript doesn't have array.map
Array.prototype.map = function(f, t){
    var o = Object(this);
    var a = new Array(o.length >>> 0);
    for (var i = 0; i < a.length; ++i){ if (i in o) a[i] = f.call(t, o[i], i, o) }
    return a;
};

/// main
(function(){

if (WScript.Arguments.Length == 0){
    WScript.Echo('rename "<operator>/<pattern>/<string>/[<modifiers>]" [-f] [-r] [-d <maxdepth>] [<files>]');
    WScript.Quit(1);
}

var fso = new ActiveXObject('Scripting.FileSystemObject');

// folder is a Folder object [e.g. from fso.GetFolder()]
// fn is a function which operates on File/Folder object
var recurseFolder = function(folder, fn, depth, maxdepth){
    if (folder.Files){
        for (var e = new Enumerator(folder.Files); !e.atEnd(); e.moveNext()){
            fn(e.item())
        }
    }
    if (folder.Subfolders){
        for (var e = new Enumerator(folder.SubFolders); !e.atEnd(); e.moveNext()){
            fn(e.item());
            if (depth < maxdepth){ arguments.callee(e.item(), fn, depth + 1, maxdepth) }
        }
    }
}

// expand wildcards (asterisk [*] and question mark [?]) recursively
// given path may be relative, and may contain environment variables.
// but wildcards only work for the filename part of a path.
// return an array of full paths of matched files.
// {{{
var expandWildcardsRecursively = function(n, md){
    var pattern = fso.GetFileName(n);
    // escape regex metacharacters (except  \, /, * and ?)
    // \ and / wouldn't appear in filename
    // * and ? are treated as wildcards
    pattern = pattern.replace(/([\[\](){}^$.+|-])/g, '\\$1');
    pattern = pattern.replace(/\*/g, '.*');  // * matches zero or more characters
    pattern = pattern.replace(/\?/g, '.');  // ? matches one character
    pattern = pattern.replace(/^(.*)$/, '\^$1\
);  // matches the whole filename
    var re = new RegExp(pattern, 'i');  // case insensitive
    var folder = fso.GetFolder(fso.GetParentFolderName(fso.GetAbsolutePathName(n)));
    var l = [];
    recurseFolder(folder, function(i){ if (i.Name.match(re)) l.push(i.Path) }, 0, md);
    return l;
}
// }}}

// parse "<operator>/<pattern>/<string>/[<modifiers>]"
// return an array splitted at unescaped forward slashes
// {{{
var parseExpr = function(s){
    // javascript regex doesn't have lookbehind...
    // reverse the string and lookahead to parse unescaped forward slashes.
    var z = s.split('').reverse().join('');

    // match unescaped forward slashes and get their positions.
    var re = /\/(\\\\)*(?!\\)/g;
    var l = [];
    while (m = re.exec(z)){ l.push(m.index) }

    // split s at unescaped forward slashes.
    var b = [0].concat(l.map(function(x){ return s.length - x }).reverse());
    var e = (l.map(function(x){ return s.length - x - 1 }).reverse()).concat([s.length]);
    return b.map(function(_, i){ return s.substring(b[i], e[i]) });
}
// }}}

var expr = WScript.Arguments(0);
var args = [];
var options = {};

for (var i = 1; i < WScript.Arguments.Length; ++i){
    if (WScript.Arguments(i).substring(0, 1) != '-'){
        args.push(WScript.Arguments(i));
    } else if (WScript.Arguments(i) == '-f'){
        options['fullpath'] = true;
    } else if (WScript.Arguments(i) == '-r'){
        options['recursive'] = true;
    } else if (WScript.Arguments(i) == '-d'){
        options['maxdepth'] = WScript.Arguments(++i);
    } else if (WScript.Arguments(i) == '--'){
        continue;
    } else {
        WScript.Echo('invalid option \'' + WScript.Arguments(i) +'\'');
        WScript.Quit(1);
    }
}

if (options['maxdepth']){
    var md = options['maxdepth'];
} else if (options['recursive']){
    var md = 1<<31>>>0;
} else {
    var md = 0;
}

var tokens = parseExpr(expr);
if (tokens.length != 4){
    WScript.Echo('error parsing expression \'' + expr + '\'.');
    WScript.Quit(1);
}
if (tokens[0] != 's'){
    WScript.Echo('<operator> must be s.');
    WScript.Quit(1);
}

var pattern = tokens[1];
var substr = tokens[2];
var modifiers = tokens[3];
var re = new RegExp(pattern, modifiers);

for (var i = 0; i < args.length; ++i){
    var l = expandWildcardsRecursively(args[i], md);
    for (var j = 0; j < l.length; ++j){
        var original = l[j];
        if (options['fullpath']){
            var nouveau = original.replace(re, substr);
        } else {
            var nouveau = fso.GetParentFolderName(original) + '\\' + fso.GetFileName(original).replace(re, substr);
        }
        if (nouveau != original){
            (fso.FileExists(original) && fso.GetFile(original) || fso.GetFolder(original)).Move(nouveau)
        }
    }
}

})();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文