Пакетное переименование последовательных файлов путем заполнения нулями - PullRequest
29 голосов
/ 24 марта 2011

У меня есть куча файлов, названных так:

output_1.png
output_2.png
...
output_10.png
...
output_120.png

Какой самый простой способ переименовать их в соответствии с соглашением, например, с максимум четырьмя десятичными знаками, чтобы файлы имели имена:

output_0001.png
output_0002.png
...
output_0010.png
output_0120.png

Это должно быть легко в Unix / Linux / BSD, хотя у меня также есть доступ к Windows. Любой язык хорош, но меня интересуют действительно аккуратные строки (если они есть?).

Ответы [ 7 ]

40 голосов
/ 24 марта 2011

Python

import os
path = '/path/to/files/'
for filename in os.listdir(path):
    prefix, num = filename[:-4].split('_')
    num = num.zfill(4)
    new_filename = prefix + "_" + num + ".png"
    os.rename(os.path.join(path, filename), os.path.join(path, new_filename))

Вы можете составить список допустимых имен файлов, предполагая, что все файлы, которые начинаются с «output_» и заканчиваются на «.png», являются действительными файлами:

l = [(x, "output" + x[7:-4].zfill(4) + ".png") for x in os.listdir(path) if x.startswith("output_") and x.endswith(".png")]

for oldname, newname in l:
    os.rename(os.path.join(path,oldname), os.path.join(path,newname))

Bash

(из: http://www.walkingrandomly.com/?p=2850)

Другими словами, я заменяю file1.png на file001.png и file20.png на file020.png и т. Д. Вот как это сделатьсделайте это в bash

#!/bin/bash
num=`expr match "$1" '[^0-9]*\([0-9]\+\).*'`
paddednum=`printf "%03d" $num`
echo ${1/$num/$paddednum}

Сохраните вышеупомянутое в файл с именем zeropad.sh и затем выполните следующую команду, чтобы сделать его исполняемым

chmod +x ./zeropad.sh

Затем вы можете использовать zeropad.shСценарий выглядит следующим образом:

./zeropad.sh frame1.png

, который будет возвращать результат

frame001.png

Осталось только использовать этот сценарий для переименования всех файлов .png в текущем каталоге, чтобы ониzeropadded.

for i in *.png;do mv $i `./zeropad.sh $i`; done

Perl

(из: Переименование нулевого планшета, например, Image (2) .jpg -> Image (002) .jpg )

use strict;
use warnings;
use File::Find;

sub pad_left {
   my $num = shift;

   if ($num < 10) {
      $num = "00$num";
   }
   elsif ($num < 100) {
      $num = "0$num";
   }

   return $num;
}

sub new_name {
   if (/\.jpg$/) {
      my $name = $File::Find::name;
      my $new_name;
      ($new_name = $name) =~ s/^(.+\/[\w ]+\()(\d+)\)/$1 . &pad_left($2) .')'/e;
      rename($name, $new_name);
      print "$name --> $new_name\n";
   }
}

chomp(my $localdir = `pwd`);# invoke the script in the parent-directory of the
                            # image-containing sub-directories

find(\&new_name, $localdir);

Переименовать

Также сверху ответ:

rename 's/\d+/sprintf("%04d",$&)/e' *.png
13 голосов
/ 24 марта 2011

Довольно просто, хотя он сочетает в себе несколько функций, которые не сразу очевидны:

@echo off
setlocal enableextensions enabledelayedexpansion
rem iterate over all PNG files:
for %%f in (*.png) do (
    rem store file name without extension
    set FileName=%%~nf
    rem strip the "output_"
    set FileName=!FileName:output_=!
    rem Add leading zeroes:
    set FileName=000!FileName!
    rem Trim to only four digits, from the end
    set FileName=!FileName:~-4!
    rem Add "output_" and extension again
    set FileName=output_!FileName!%%~xf
    rem Rename the file
    rename "%%f" "!FileName!"
)

Редактировать: Неправильное прочтение, что вы ищете не пакетный файл, а любое решение на любом языке.Простите за это.Чтобы восполнить это, однострочник PowerShell:

gci *.png|%{rni $_ ('output_{0:0000}.png' -f +($_.basename-split'_')[1])}

Вставьте туда ?{$_.basename-match'_\d+'}, если у вас есть другие файлы, которые не соответствуют этому шаблону.

5 голосов
/ 10 февраля 2015

Мне просто нужно было сделать это на OSX. Вот сценарии, которые я создал для него - одна строка!

> for i in output_*.png;do mv $i `printf output_%04d.png $(echo $i | sed 's/[^0-9]*//g')`; done
2 голосов
/ 18 декабря 2014

Здесь - это написанный на Python скрипт, который дополняет нулями в зависимости от наибольшего числа и игнорирует ненумерованные файлы в данном каталоге. Использование:

python ensure_zero_padding_in_numbering_of_files.py /path/to/directory

Тело сценария:

import argparse
import os
import re
import sys

def main(cmdline):

    parser = argparse.ArgumentParser(
        description='Ensure zero padding in numbering of files.')
    parser.add_argument('path', type=str,
        help='path to the directory containing the files')
    args = parser.parse_args()
    path = args.path

    numbered = re.compile(r'(.*?)(\d+)\.(.*)')

    numbered_fnames = [fname for fname in os.listdir(path)
                       if numbered.search(fname)]

    max_digits = max(len(numbered.search(fname).group(2))
                     for fname in numbered_fnames)

    for fname in numbered_fnames:
        _, prefix, num, ext, _  = numbered.split(fname, maxsplit=1)
        num = num.zfill(max_digits)
        new_fname = "{}{}.{}".format(prefix, num, ext)
        if fname != new_fname:
            os.rename(os.path.join(path, fname), os.path.join(path, new_fname))
            print "Renamed {} to {}".format(fname, new_fname)
        else:
            print "{} seems fine".format(fname)

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
2 голосов
/ 24 марта 2011

Для массового переименования единственным безопасным решением является mmv - оно проверяет наличие коллизий и позволяет переименовывать в цепочках и циклах, что выходит за рамки большинства сценариев. К сожалению, нулевое заполнение не слишком жарко. Ароматизатор:

c:> mmv output_[0-9].png output_000#1.png

Вот один из обходных путей:

c:> type file
mmv
[^0-9][0-9] #1\00#2
[^0-9][0-9][^0-9] #1\00#2#3
[^0-9][0-9][0-9] #1\0#2#3
[^0-9][0-9][0-9][^0-9] #1\0#2#3
c:> mmv <file
1 голос
/ 18 июля 2014
$rename output_ output_0 output_?   # adding 1 zero to names ended in 1 digit
$rename output_ output_0 output_??  # adding 1 zero to names ended in 2 digits
$rename output_ output_0 output_??? # adding 1 zero to names ended in 3 digits

Вот и все!

0 голосов
/ 01 февраля 2018

Я слежу за решением Адама для OSX.

Некоторые ошибки, с которыми я столкнулся в моем сценарии, были:

  1. У меня был набор файлов .mp3, поэтому sed перехватывал ' 3 ' в суффиксе ' .mp3 '. (Я использовал basename вместо echo, чтобы исправить это)
  2. Мои .mp3 имели пробелы в своих именах, например, " audio track 1.mp3 ", это приводило к тому, что basename + sed немного облажались, поэтому мне пришлось цитировать "$ i "параметр.

В итоге моя строка конверсии выглядела так:

for i in *.mp3 ; do mv "$i" `printf "track_%02d.mp3\n" $(basename "$i" .mp3 | sed 's/[^0-9]*//g')` ; done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...