Rename large mass of files

2

I'm trying to create a java script to rename a large amount of files by applying a pattern to the formatting that would be:

  • First capital letter and the lower case letter.
  • Composite names with more than one word should follow the above pattern for each name.
  • The file extension should be minuscule.

Given this, I have 3 template files:
douglas leonardo.smc
XGR - STS.SMC
xpto.smc

I want the following result:
Douglas Leonardo.smc
Xgr - Sts.smc
Xpto.smc

In the douglas leonardo.smc file, I was able to leave the d of uppercase douglas, but the leonardo l did not. The file is asm:
Douglas leonardo.smc.

In short: When the String is composed of more than one word, only the first one I can leave starting with a capital letter, the rest does not. How can I resolve?

import java.io.File;

public class RenomeiaArquivos {

    public static void main(String[] args) {
        File diretorio = new File("/home/douglas/Documentos/roms");
        File[] files = diretorio.listFiles();

        for (int i = 0; i < files.length; i++) {
            String nomeArquivo = files[i].getName();
            nomeArquivo = nomeArquivo.toLowerCase();
            String primeiraMaiuscula;
            primeiraMaiuscula = nomeArquivo.substring(0, 1).toUpperCase();
            String restanteMiniscula;
            restanteMiniscula = nomeArquivo.substring(1);

            nomeArquivo = primeiraMaiuscula + restanteMiniscula;

            System.out.println(nomeArquivo);

        }

    }

}
    
asked by anonymous 04.03.2016 / 20:33

2 answers

2

First you can split the spaces, then go to each part by changing the first letter, and finally send the extension to lowercase , here is a complete code:

String ext = "";
if(nome.lastIndexOf(".")>0){
    ext = nome.substring(nome.lastIndexOf(".")).toLowerCase();
    nome= nome.substring(0,nome.lastIndexOf(".")).toLowerCase();
}
String nomeFinal = "";
String partes[] = nome.split("\s+");
for(int i =0; i<partes.length; i++){
    nomeFinal += " " +  
        (partes[i].substring(0, 1).toUpperCase() + 
        partes[i].length()>1 ? partes[i].substring(1) : "");
}
nomeFinal = nomeFinal.substring(1) + ext;//Pra remover um espaço que fica no inicio devido ao 1 for 
    
04.03.2016 / 20:49
1

Using regular expressions would give you a bit more flexibility. Here's an example:

public class WordUpperCaseExample {

    public static final Locale pt_BR = new Locale("pt","BR");

    public static void main(String[] args) {
        String[] examples = { "douglas léonardo.smc", "XGR - STS.SMC", "xpto.smc", "aRqUiVo_cOmPoStO.tXt", "aRqUiVo-cOmPoStO.tXt", "123nome.txt" };
        for (String e : examples) {
            System.out.println(upperCaseWords(e));
        }
    }

    public static String upperCaseWords(String phrase) {
        Matcher m = Pattern.compile("\.?[\p{IsAlphabetic}][\w\d&&[^_]]*", Pattern.UNICODE_CHARACTER_CLASS).matcher(phrase);
        StringBuffer sb  = new StringBuffer();
        while (m.find()) m.appendReplacement(sb, upperCaseFirst(m.group()));
        return m.appendTail(sb).toString();
    }

    public static String upperCaseFirst(String word) {
        return word.isEmpty() ? word :
                word.length() == 1 ? word.toUpperCase(pt_BR) :
                        word.startsWith(".") ? word.toLowerCase(pt_BR) : (word.substring(0, 1).toUpperCase(pt_BR) + word.substring(1).toLowerCase(pt_BR));
    }

}

The regular expression \.?[\p{IsAlphabetic}][\w\d&&[^_]]* may seem complex, but it looks for words that:

  • \.? : optionally start with a dot, which would be the file extension. So I check if the captured group starts with a dot, and if true, it converts everything to lowercase.
  • [\p{IsAlphabetic}] : The force that the first character of the group captured by the expression is an alphabetic character in the Unicode table. This causes, for example, 123nome to 123Nome , since the expression will capture just beginning from the first letter. This restriction also causes other characters dividing words not to be captured.
  • [\w\d&&[^_]]* causes other letters and numbers to be captured while &&[^_] ignores underscore . This causes abc_abc to Abc_Abc .
  • In addition, the parameter Pattern.UNICODE_CHARACTER_CLASS causes characters in the Unicode table to be considered, so, for example, \w will capture accented characters like á in addition to those belonging to the ASCII pattern as a .

    The upperCaseFirst method converts each word. It contains any additional logic needed to convert a captured word. The rules of the above example are:

  • Empty word, it does nothing. This is only for precaution, since the regular expression does not allow this to occur. Thus the method can be reused with security and efficiency.
  • Word with a character, converts to upper case. However you may want to change this so that olhe a casa Olhe a Casa and not Olhe A Casa as it is now.
  • If the word begins with a period, it converts to lowercase. This is to handle the file extension case, but it can cause side effects if there are other points in the file name. If you want to handle this, it is better to treat the extension separately as in the reply in Rodrigo.
  • In all other cases, convert the first character to upper case and the rest to lowercase. Note that I always specify the locale to perform the conversion operations. This avoids possible inconsistencies if the program runs in different environments where the Java language is different.
  • The general idea of the implementation is that you can easily add and modify the rules by changing the regular expression as Documentation of class Pattern allows and also the upperCaseFirst method.

        
    07.03.2016 / 03:01