BRT - Bulk Renaming Tool

Publicado por Pedro Fernandes (última atualização em 25/03/2024)

[ Hits: 883 ]

Homepage: https://github.com/PedroF37

Download BRT.tar.gz




Projeto em C de um utilitário de renomeação em massa de arquivos pela linha de comando. Pode inserir antes do nome, adicionar depois de string alvo no nome, substituir antigo por novo e deletar sub string em nome de arquivo.

Programa usa recursividade, então varre o diretório alvo e os seus subdiretórios e renomeia todos os arquivos alvo. Programa também permite executar todas as operações filtrando pela extensão do arquivo, então, as operações são executadas nos nomes de arquivos que correspondem com o alvo, mas apenas os que têm a extensão indicada.

Códigos fontes, um Makefile e restantes instruções, assim como exemplos de uso estão no repositório do projeto:
https://github.com/PedroF37/BRT

Grato!

  



Esconder código-fonte

Arquivos brt.c e brt.h:

#include "brt.h"
#include "helper.h"
#include "args.h"


#define ARG_MIN 5
#define ARG_MAX 7


int main(int argc, char **argv)
{
    if (argc < ARG_MIN || argc > ARG_MAX)
    {
        print_usage();
        return(EXIT_FAILURE);
    }

    if (!is_valid_directory(*(argv + 1)))
    {
        fprintf(stderr, "Diretório %s é inválido ou"
            " você não tem permissões\n", *(argv + 1));
        return(EXIT_FAILURE);
    }

    argv++;
    map_operation(argc - 3, argv);
    return(EXIT_SUCCESS);
}


#ifndef _BRT_H
#define _BRT_H


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <libgen.h>

#include <fileutils.h>
#include <dirutils.h>
#include <strutils.h>


#endif


/****************************************************************************************************************************************/


Arquivos args.c e args.h


#include "brt.h"
#include "args.h"
#include "helper.h"


void number_args(int argc, int args)
{
    if (argc != args)
    {
        print_usage();
        exit(EXIT_FAILURE);
    }

    return;
}


void map_operation(int argc, char **argv)
{
    Operation operation;
    char *directory = *argv++;
    char *operation_str = *argv++;
    remove_last_char(directory, '/');

    if (strcmp(operation_str, "-a") == 0 ||
        strcmp(operation_str, "--add") == 0)
    {
        number_args(argc, 2);
        operation = ADD;
    }
    else if (strcmp(operation_str, "-i") == 0 ||
        strcmp(operation_str, "--insert") == 0)
    {
        number_args(argc, 2);
        operation = INSERT;
    }
    else if (strcmp(operation_str, "-ae") == 0 ||
        strcmp(operation_str, "--add-ext") == 0)
    {
        number_args(argc, 3);
        operation = ADD_EXT;
    }
    else if (strcmp(operation_str, "-ie") == 0 ||
        strcmp(operation_str, "--insert-ext") == 0)
    {
        number_args(argc, 3);
        operation = INSERT_EXT;
    }
    else if (strcmp(operation_str, "-r") == 0 ||
        strcmp(operation_str, "--replace") == 0)
    {
        number_args(argc, 3);
        operation = REPLACE;
    }
    else if (strcmp(operation_str, "-re") == 0 ||
        strcmp(operation_str, "--replace-ext") == 0)
    {
        number_args(argc, 4);
        operation = REPLACE_EXT;
    }
    else if (strcmp(operation_str, "-d") == 0 ||
        strcmp(operation_str, "--delete") == 0)
    {
        number_args(argc, 2);
        operation = DELETE;
    }
    else if (strcmp(operation_str, "-de") == 0 ||
        strcmp(operation_str, "--delete-ext") == 0)
    {
        number_args(argc, 3);
        operation = DELETE_EXT;
    }
    else
    {
        print_usage();
        exit(EXIT_FAILURE);
    }

    search_directory(operation, directory, argv);
}


#ifndef _ARGS_H
#define _ARGS_H


/* A operação de renomeação */
typedef enum OperationType
{
    ADD, INSERT, ADD_EXT,
    INSERT_EXT, REPLACE,
    REPLACE_EXT, DELETE,
    DELETE_EXT
}
Operation;


/* Cuida de garantir o número certo de argumentos */
void number_args(int argc, int args);


/* Cuida de mapear a operação a ser executada */
void map_operation(int argc, char **argv);


#endif


/*****************************************************************************************************************************/


Arquivos helper.c e helper.h


#include "brt.h"
#include "helper.h"


void print_usage()
{
    printf("\nBulk Renaming Tool - Renomeação em Massa de Arquivos\n\n"
           "Uso: brt Diretório OPÇÃO ALVO\n\n"
           "OPÇÕES:\n"
           "  -a, --add            Alvo Adicionar\n"
           "  -i, --insert         Alvo Inserir\n"
           "  -ae, --add-ext       Alvo Adicionar Extensão\n"
           "  -ie, --insert-ext    Alvo Inserir Extensão\n"
           "  -r, --replace        Alvo Antigo Novo\n"
           "  -re, --replace-ext   Alvo Antigo Novo Extensão\n"
           "  -d, --delete         Alvo Deletar\n"
           "  -de, --delete-ext    Alvo Deletar Extensão\n\n"
           "Todas as operações executadas são feitas usando recursão no diretório alvo\n\n"
           "Exemplos:\n\n"
           "  $ brt /home/usuario/Documentos -a curriculum -profissional\n"
           "     Adiciona '-profissional' depois de 'curriculum', a todos os arquivos em Documentos com 'curriculum' no nome\n"
           "  $ brt ~/Imagens -i Férias-de-Verão Minhas-\n"
           "     Insere antes de 'Férias-de-Verão' 'Minhas-' em todos os arquivos em Imagens com 'Férias-de-Verão' no nome\n"
           "  $ brt ~/Videos --add-ext Aniversário -2023 mp4\n"
           "     Adiciona '-2023' depois de 'Aniversário' em todos os arquivos em Videos com 'Aniversário' no nome, mas apenas os que têm a extensão 'mp4'\n"
           "  $ brt ~/Videos -ie Aniversário Minha-Festa-de- mkv\n"
           "     Insere antes de 'Aniversário' 'Minha-Festa-de-' em todos os arquivos em Videos com 'Aniversário' no nome, mas apenas os que têm a extensão 'mkv'\n"
           "  $ brt /home/usuario/Imagens --replace Natal _2021 _2022\n"
           "     Substitui em Imagens '_2021' por '_2022' em todos os arquivos com 'Natal' no nome\n"
           "  $ brt ~/Imagens -re Natal _2021 _2022 jpg\n"
           "     Sustitui em Imagens '_2021' por '_2022' em todos os arquivos com 'Natal' no nome, mas apenas os que têm a extensão 'jpg'\n"
           "  $ brt ~/Documentos -d curriculum -profissional\n"
           "     Deleta em Documentos '-profissional' em todos os arquivos com 'curriculum' no nome\n"
           "  $ brt ~/Documentos --delete-ext curriculum -profissional docx\n"
           "     Deleta em Documentos '-profissional' em todos os arquivos com 'curriculum' no nome mas apenas os que têm a extensão 'docx'\n\n");
    return;
}


bool is_renamed(char *pathname, char *new_name)
{
    if (rename(pathname, new_name) != 0)
    {
        return(false);
    }

    return(true);
}


bool has_same_extension(char *pathname, char *extension)
{
    char *ext;
    if ((ext = has_extension(pathname)) == NULL)
    {
        return(false);
    }

    if (strcmp(ext, extension) != 0)
    {
        return(false);
    }

    return(true);
}


char *remove_dot_from_extension(char *extension)
{
    char *new_ext;
    if ((new_ext = strrchr(extension, '.')) != NULL)
    {
        return(new_ext + 1);
    }

    return(extension);
}


Result call_operation(Operation operation,
    char *pathname, char **argv)
{
    Result result;
    char *ext = NULL;
    switch (operation)
    {
        case ADD:
            result = add_in_filename(pathname,
                *argv, *(argv + 1));
            break;

        case INSERT:
            result = insert_in_filename(pathname,
                *(argv + 1));
            break;

        case ADD_EXT:
            ext = remove_dot_from_extension(*(argv + 2));
            result = add_in_filename_ext(pathname,
                *argv, *(argv + 1), ext);
            break;

        case INSERT_EXT:
            ext = remove_dot_from_extension(*(argv + 2));
            result = insert_in_filename_ext(pathname,
                *(argv + 1) ,ext);
            break;

        case REPLACE:
            result = replace_in_filename(pathname,
                *(argv + 1), *(argv + 2));
            break;

        case REPLACE_EXT:
            ext = remove_dot_from_extension(*(argv + 3));
            result = replace_in_filename_ext(pathname,
                *(argv + 1), *(argv + 2), ext);
            break;

        case DELETE:
            result = delete_in_filename(pathname,
                *(argv + 1));
            break;

        case DELETE_EXT:
            ext = remove_dot_from_extension(*(argv + 2));
            result = delete_in_filename_ext(pathname,
                *(argv + 1), ext);
            break;
    }

    return(result);
}


void search_directory(Operation operation,
    char *directory, char **argv)
{
    DIR *dhandle;
    if ((dhandle = opendir(directory)) == NULL)
    {
        fprintf(stderr, "Erro abrindo %s\n", directory);
        closedir(dhandle);
        exit(EXIT_FAILURE);
    }

    struct dirent *entry;
    Result result;
    while ((entry = readdir(dhandle)) != NULL)
    {
        char *fullpath;
        if ((fullpath = create_pathname(directory,
            entry->d_name)) == NULL)
        {
            fprintf(stderr, "Erro criando"
                " caminho para %s\n", entry->d_name);
            closedir(dhandle);
            exit(EXIT_FAILURE);
        }

        if (is_dot_directory(entry->d_name) ||
            is_simlink(fullpath))
        {
            continue;
        }

        if (is_directory(fullpath))
        {
            remove_last_char(fullpath, '/');
            search_directory(operation, fullpath, argv);
        }

        if (is_equal_name(basename(fullpath), *argv) == false)
        {
            continue;
        }

        if ((result = call_operation(operation,
            fullpath, argv)) != SUCCESS)
        {
            if (result == CONTINUE)
            {
                continue;
            }
            else
            {
                closedir(dhandle);
                exit(EXIT_FAILURE);
            }
        }

        free(fullpath);
    }

    closedir(dhandle);
}


#ifndef _HELPER_H
#define _HELPER_H


#include "operations.h"
#include "args.h"

/* Cuida de mostrar como usar o programa */
void print_usage();


/* Renomeia e retorna true ou false
 * para se foi ou não renomeado */
bool is_renamed(char *pathname, char *new_name);


/* Cuida de verificar que se tem extensão e se são iguais */
bool has_same_extension(char *pathname, char *extension);


/* Cuida de remover o . de ".pdf", etc, caso tenha digitado . */
char *remove_dot_from_extension(char *extension);


/* Cuida de chamar a operação apropriada */
Result call_operation(Operation operation,
    char *pathname, char **argv);


/* Cuida de varrer o diretório alvo recursivamente */
void search_directory(Operation operation,
    char *directory, char **argv);

#endif


/**************************************************************************************************************/


Arquivos operations.c e operations.h


#include "brt.h"
#include "operations.h"
#include "helper.h"


Result add_in_filename(char *pathname,
    char *target, char *addition)
{
    char *new_name;
    if ((new_name = str_insert(pathname,
        target, addition)) == NULL)
    {
        return(FAILURE);
    }

    if (is_renamed(pathname,
        new_name) == false)
    {
        free(new_name);
        return(FAILURE);
    }

    printf("%s -->> %s\n", pathname, new_name);

    free(new_name);
    return(SUCCESS);
}


Result insert_in_filename(char *pathname, char *insert)
{
    char *new_name;
    if ((new_name = insert_in_beginning(basename(
        pathname), insert)) == NULL)
    {
        return(FAILURE);
    }

    char *pathname_copy = duplicate(pathname);
    if (pathname_copy == NULL)
    {
        free(new_name);
        return(FAILURE);
    }

    char *full_new_name;
    if ((full_new_name = create_pathname(
        dirname(pathname_copy), new_name)) == NULL)
    {
        free(pathname_copy);
        free(new_name);
        return(FAILURE);
    }

    if (is_renamed(pathname,
        full_new_name) == false)
    {
        free(pathname_copy);
        free(full_new_name);
        free(new_name);
        return(FAILURE);
    }

    printf("%s -->> %s\n", pathname, full_new_name);

    free(pathname_copy);
    free(full_new_name);
    free(new_name);
    return(SUCCESS);
}


Result add_in_filename_ext(char *pathname,
    char *target, char *addition, char *extension)
{
    if (has_same_extension(pathname,
        extension) == false)
    {
        return(CONTINUE);
    }

    char *new_name;
    if ((new_name = str_insert(pathname,
        target, addition)) == NULL)
    {
        return(FAILURE);
    }

    if (is_renamed(pathname, new_name) == false)
    {
        free(new_name);
        return(FAILURE);
    }

    printf("%s -->> %s\n", pathname, new_name);

    free(new_name);
    return(SUCCESS);
}


Result insert_in_filename_ext(char *pathname,
    char *insert, char *extension)
{
    if (has_same_extension(pathname,
        extension) == false)
    {
        return(CONTINUE);
    }

    char *new_name;
    if ((new_name = insert_in_beginning(
        basename(pathname), insert)) == NULL)
    {
        return(FAILURE);
    }

    char *pathname_copy = duplicate(pathname);
    if (pathname_copy == NULL)
    {
        free(new_name);
        return(FAILURE);
    }

    char *full_new_name;
    if ((full_new_name = create_pathname(
        dirname(pathname_copy), new_name)) == NULL)
    {
        free(pathname_copy);
        free(new_name);
        return(FAILURE);
    }

    if (is_renamed(pathname,
        full_new_name) == false)
    {
        free(pathname_copy);
        free(full_new_name);
        free(new_name);
        return(FAILURE);
    }

    printf("%s -->> %s\n", pathname, full_new_name);

    free(pathname_copy);
    free(full_new_name);
    free(new_name);
    return(SUCCESS);
}


Result replace_in_filename(char *pathname,
    char *old_str, char *new_str)
{
    char *new_name;
    if ((new_name = str_replace(pathname,
        old_str, new_str)) == NULL)
    {
        return(FAILURE);
    }

    if (is_renamed(pathname, new_name) == false)
    {
        free(new_name);
        return(FAILURE);
    }

    printf("%s -->> %s\n", pathname, new_name);

    free(new_name);
    return(SUCCESS);
}


Result replace_in_filename_ext(char *pathname,
    char *old_str, char *new_str, char *extension)
{
    if (has_same_extension(pathname,
        extension) == false)
    {
        return(CONTINUE);
    }

    char *new_name;
    if ((new_name = str_replace(pathname,
        old_str, new_str)) == NULL)
    {
        return(FAILURE);
    }

    if (is_renamed(pathname, new_name) == false)
    {
        free(new_name);
        return(FAILURE);
    }

    printf("%s -->> %s\n", pathname, new_name);

    free(new_name);
    return(SUCCESS);
}


Result delete_in_filename(char *pathname, char *to_delete)
{
    char *new_name;
    if ((new_name = str_remove(pathname,
        to_delete)) == NULL)
    {
        return(FAILURE);
    }

    if (is_renamed(pathname, new_name) == false)
    {
        free(new_name);
        return(FAILURE);
    }

    printf("%s -->> %s\n", pathname, new_name);

    free(new_name);
    return(SUCCESS);
}


Result delete_in_filename_ext(char *pathname,
    char *to_delete, char *extension)
{
   if (has_same_extension(pathname,
        extension) == false)
   {
       return(CONTINUE);
   }

    char *new_name;
    if ((new_name = str_remove(pathname,
        to_delete)) == NULL)
    {
        return(FAILURE);
    }

    if (is_renamed(pathname, new_name) == false)
    {
        free(new_name);
        return(FAILURE);
    }

    printf("%s -->> %s\n", pathname, new_name);

    free(new_name);
    return(SUCCESS);
}


#ifndef _OPERATIONS_H
#define _OPERATIONS_H


/* O resultado da operação escolhida */
typedef enum OperationResult
{
    SUCCESS, CONTINUE, FAILURE
}
Result;


/* Cuida de adicionar no nome depois de target */
Result add_in_filename(char *pathname, char *target, char *addition);


/* Cuida de inserir no nome antes de target */
Result insert_in_filename(char *pathname, char *insert);


/* Cuida de adicionar no nome depois de target, filtrando por extensão*/
Result add_in_filename_ext(char *pathname, char *target,
    char *addition, char *extension);


/* Cuida de inserir no nome antes de target, filtrando por extensão*/
Result insert_in_filename_ext(char *pathname,
    char *insert, char *extension);


/* Cuida de substituir old_str por new_str nos
 * arquivos com target no nome */
Result replace_in_filename(char *pathname,
    char *old_str, char *new_str);


/* Cuida de substituir old_str por new_str nos
 * arquivos com target no nome, filtrando por extensão*/
Result replace_in_filename_ext(char *pathname,
    char *old_str, char *new_str, char *extension);


/* Cuida de deletar to_delete nos arquivos com target no nome */
Result delete_in_filename(char *pathname, char *to_delete);


/* Cuida de deletar to_delete nos arquivos com
 * target no nome, filtrando por extensão*/
Result delete_in_filename_ext(char *pathname,
    char *to_delete, char *extension);


#endif

Scripts recomendados

Pequeno simulador de Banco de Dados

Leitura de arquivo texto separando as colunas

Cadastor de Produtos em C e metodos ordenação

Ler config

Vi para Windows


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts