根据查找批量重命名文件

7 投票
9 回答
6424 浏览
提问于 2025-04-16 06:49

我有一个文件夹,里面全是图片文件,比如:

  • 1500000704_full.jpg
  • 1500000705_full.jpg
  • 1500000711_full.jpg
  • 1500000712_full.jpg
  • 1500000714_full.jpg
  • 1500000744_full.jpg
  • 1500000745_full.jpg
  • 1500000802_full.jpg
  • 1500000803_full.jpg

我需要根据一个文本文件里的内容来重命名这些文件,这个文本文件的内容像这样:

  • SH103239 1500000704
  • SH103240 1500000705
  • SH103241 1500000711
  • SH103242 1500000712
  • SH103243 1500000714
  • SH103244 1500000744
  • SH103245 1500000745
  • SH103252 1500000802
  • SH103253 1500000803
  • SH103254 1500000804

所以,我想把这些图片文件重命名为:

  • SH103239_full.jpg
  • SH103240_full.jpg
  • SH103241_full.jpg
  • SH103242_full.jpg
  • SH103243_full.jpg
  • SH103244_full.jpg
  • SH103245_full.jpg
  • SH103252_full.jpg
  • SH103253_full.jpg
  • SH103254_full.jpg

我该怎么做才能最简单呢?有没有人能给我写个快速的命令或者脚本来帮我完成这个任务?因为我有很多这样的图片文件,手动修改实在是太麻烦了。

我在用ubuntu,但如果需要的话可以换到windows。理想情况下,我希望能用bash脚本,这样我也能学到更多,或者用简单的perl或python。

谢谢

编辑:需要更改文件名

9 个回答

2

这是对Wesley代码的重写,使用了生成器:

import os, os.path

with open('mapping.txt') as mapping_file:
    mapping = dict(line.strip().split() for line in mapping_file)

rootextiter = ((filename, os.path.splitext(filename)) for filename in os.listdir('.'))
mappediter = (
    (filename, os.path.join(mapping[root], extension))
    for filename, root, extension in rootextiter
    if root in mapping
)
for oldname, newname in mappediter:
    os.rename(oldname, newname)
5

这个方法可以解决你的问题:

#!/usr/bin/perl
while (<DATA>) {
    my($new, $old) = split;
    rename("$old.jpg", "$new.jpg")
        || die "can't rename "$old.jpg", "$new.jpg": $!";
}
__END__
SH103239 1500000704
SH103240 1500000705
SH103241 1500000711
SH103242 1500000712
SH103243 1500000714
SH103244 1500000744
SH103245 1500000745
SH103252 1500000802
SH103253 1500000803
SH103254 1500000804

DATA 换成 ARGV,这样就可以从指定的输入文件中读取内容了。

通常在进行批量重命名操作时,我会用更像这样的方式:

#!/usr/bin/perl
# rename script by Larry Wall
#
# eg:
#      rename 's/\.orig$//'  *.orig
#      rename 'y/A-Z/a-z/ unless /^Make/'  *
#      rename '$_ .= ".bad"'  *.f
#      rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i'  *
#      find /tmp -name '*~' -print | rename 's/^(.+)~$/.#$1/'

($op = shift) || die "Usage: rename expr [files]\n";

chomp(@ARGV = <STDIN>) unless @ARGV;

for (@ARGV) {
    $was = $_;
    eval $op;
    die if $@;  # means eval `failed'
    rename($was,$_) unless $was eq $_;
}

我有一个功能更全的版本,不过这个就够用了。

9

这里有一个简单的Python 2脚本,用来进行文件重命名。

#!/usr/bin/env python

import os

# A dict with keys being the old filenames and values being the new filenames
mapping = {}

# Read through the mapping file line-by-line and populate 'mapping'
with open('mapping.txt') as mapping_file:
    for line in mapping_file:
        # Split the line along whitespace
        # Note: this fails if your filenames have whitespace
        new_name, old_name = line.split()
        mapping[old_name] = new_name

suffix = '_full'

# List the files in the current directory
for filename in os.listdir('.'):
    root, extension = os.path.splitext(filename)
    if not root.endswith(suffix):
        # File doesn't end with this suffix; ignore it
        continue
    # Strip off the number of characters that make up suffix
    stripped_root = root[:-len(suffix)]
    if stripped_root in mapping:
        os.rename(filename, ''.join(mapping[stripped_root] + suffix + extension))

这个脚本里有一些地方是写死的,也就是说这些内容不应该固定死,比如映射文件的名字(mapping.txt)和文件名的后缀(_full)。这些内容其实可以通过参数传入,然后用sys.argv来处理。

撰写回答