Mover a última parte do nome do arquivo para frente

2

Eu tenho vários arquivos nomeados assim: This is a test - AB12-1998.avi

(o último código é sempre 2 letras, 2 números, traço, 4 dígitos)

O que eu gostaria de fazer é renomeá-los assim: AB12-1998 - This is a test.avi

Eu aprecio qualquer solução que você possa me dar usando bash, renomear ou de qualquer outra forma, desde que o trabalho seja feito.

    
por Mark Roi 19.05.2018 / 19:22

2 respostas

5

Com o Perl rename (*) :

rename 's/^(.*) - (.*)(\..*)$/$2 - $1$3/' *.avi

ou, se você quiser ser mais rigoroso sobre o código:

rename 's/^(.*) - ([a-zA-Z]{2}\d{2}-\d{4})(\..*)$/$2 - $1$3/' *.avi

Isso deve funcionar mesmo com nomes como foo - bar - AB12-1234.avi , já que o primeiro .* corresponde ao <space><dash><space> final.

(* veja: O que há com todas as renomeações: prename, rename, rename de arquivo? )

Ou similarmente no Bash:

for f in *.avi ; do
    if [[ "$f" =~  ^(.*)\ -\ (.*)(\..*)$ ]]; then
        mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}${BASH_REMATCH[3]}"
    fi
done

Resumidamente, os regexes são divididos em

^     start of string
( )   capture group
.*    any amount of anything
\.    a literal dot
$     end of string

A maioria dos caracteres regulares combina com eles, embora você precise escapar de espaços com barras invertidas no Bash (como acima). O conteúdo dos grupos de captura aparece em ordem em $1 , $2 etc no Perl e em ${BASH_REMATCH[1]} , ${BASH_REMATCH[2]} etc no Bash.

    
por 19.05.2018 / 19:37
2

Usando /bin/sh :

for name in *.avi; do
    n=${name%.avi}    # name without filename extension
    first=${n%% - *}  # first part of name
    last=${n#* - }    # last part of name
    new="$last - $first.avi"  # recombined new name

    printf 'Would move "%s" to "%s"\n' "$name" "$new"
    # mv -- "$name" "$new"
done

O ${parameter%%word} remove a cadeia de sufixos mais longa que corresponde a word de $parameter , enquanto ${parameter#word} remove a cadeia de prefixo mais curta que corresponde a word de $parameter . O código irá, portanto, trocar as duas sub-strings na primeira ocorrência de - (espaço-traço-espaço).

Remova o mv recomendado para realmente renomear arquivos.

Nos comentários da resposta do ilkkachu , vejo que você também quer trocar a primeira parte do nome , de modo que AB12-1998 se torne 1998-AB12 .

Como agora estamos fazendo duas operações de troca no nome, podemos colocar isso em uma função:

swap () {
    # swaps the two part of a string around
    # the swap point is defined by the first argument

    swstr=$1
    string=$2

    first=${string%%$swstr*}
    last=${string#*$swstr}

    printf '%s%s%s\n' "$last" "$swstr" "$first"
}

for name in *.avi; do
    n=${name%.avi}
    n=$( swap ' - ' "$n" )
    first=${n%% - *}
    first=$( swap '-' "$first" )
    new="$first - ${n#* - }.avi"

    printf 'Would move "%s" to "%s"\n' "$name" "$new"
    # mv -- "$name" "$new"
done

Exemplo de saída:

Would move "This is a test - AB9-1995.avi" to "1995-AB9 - This is a test.avi"
Would move "This is a test - AB9-1996.avi" to "1996-AB9 - This is a test.avi"
Would move "This is a test - AB9-1997.avi" to "1997-AB9 - This is a test.avi"
Would move "This is a test - AB9-1998.avi" to "1998-AB9 - This is a test.avi"
Would move "This is a test - AB9-1999.avi" to "1999-AB9 - This is a test.avi"
    
por 23.05.2018 / 11:28

Tags