简体   繁体   中英

Improve regex to rename files

I need help to improve the perfomance of a custom function used to rename files recursively in a directory. This is how the functions look like:

# Rename the files to Kebab Case recursively
# @param {string} $d directory name
renameToKebab() {
    d="${1:-$(pwd)}"
    # replace whitespaces and underscores with hyphens
    find $d -execdir rename 's/[ _]/-/g' '{}' \+
    # put a hyphen between words that are in Camel/Pascal case
    find $d -execdir rename 's/([a-z])([A-Z])/$1-$2/g' '{}' \+
    # replace two or more hyphens with a single hyphen
    find $d -execdir rename 's/-+/-/g' '{}' \+
    # replace -( with (
    find $d -execdir rename 's/\(-/(/g' '{}' \+
    # replace )- with )
    find $d -execdir rename 's/-\)/)/g' '{}' \+
    # transform upper case letters into lower case
    find $d -execdir rename 'y/A-Z/a-z/' '{}' \+
}

# Rename the files to underscore case recursively
# @param {string} $d directory name
renameToUnderscore() {
    d="${1:-$(pwd)}"
    find $d -execdir rename 's/[ -]/_/g' '{}' \+
    find $d -execdir rename 's/([a-z])([A-Z])/$1_$2/g' '{}' \+
    find $d -execdir rename 's/_+/_/g' '{}' \+
    find $d -execdir rename 's/\(_/(/g' '{}' \+
    find $d -execdir rename 's/_\)/)/g' '{}' \+
    find $d -execdir rename 'y/A-Z/a-z/' '{}' \+
}

This function is written in bash and is located in ~/.bash_profile . The rename command is a terminal tool that renames files using Perl regex. I'm not familiar with Perl .

The problem of the script above is that it executes the rename command six times. So, every time I run these functions it takes some seconds to rename the files. I'd like to optimize the regex so I need to execute rename only once/twice. That would make things much faster.

Thanks in advance.

Note rename version: 0.20 OS: Ubuntu 18

Here is an example of how you can do all the processing in Perl eliminating the need to call the external commands find and rename multiple times. I am only showing the first function renameToKebab() :

#! /usr/bin/env perl

use feature qw(say);
use strict;
use warnings;
use Cwd qw(getcwd);
use File::Find;

sub rename_to_kebab {
    my $d = shift || getcwd();
    find(\&rename_to_kebab_helper, $d);
}

sub rename_to_kebab_helper {
    my $orig_name = $_;

    return if ($_ eq ".") || ($_ eq ".."); 
    # replace whitespaces and underscores with hyphens
    s/[ _]/-/g;
    # put a hyphen between words that are in Camel/Pascal case
    s/([a-z])([A-Z])/$1-$2/g;
    # replace two or more hyphens with a single hyphen
    s/-+/-/g;
    # replace -( with (
    s/\(-/(/g;
    # replace )- with )
    s/-\)/)/g;
    # transform upper case letters into lower case
    y/A-Z/a-z/;
    return if $_ eq $orig_name;
    if ( -e $_ ) {
        say "File '$_' exists in directory: ", $File::Find::dir;
        say "   -> skipping";
        return;
    }
    my $success = rename $orig_name, $_;
    if ( !$success ) {
        say "Could not rename '$orig_name' to '$_': $!";
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM