Como você transpõe partes do nome do arquivo no Linux?

0

Pegue um nome de arquivo de tamanho variável 'abcdef - ghijkl.pdf' e renomeie para 'ghijkl - abcdef.pdf'

Como eu conseguiria isso em um script de linha de comando para todos os arquivos em uma única pasta?

    
por matt 05.02.2017 / 22:24

4 respostas

4

Como você está usando o Ubuntu, você deve ter pelo menos um dos rename ou prename

baseados em perl
$ rename -n -- 's/(\w*) - (\w*)/$2 - $1/' *.pdf
rename(abcdef - ghijkl.pdf, ghijkl - abcdef.pdf)

$ prename -n -- 's/(\w*) - (\w*)/$2 - $1/' *.pdf
abcdef - ghijkl.pdf renamed as ghijkl - abcdef.pdf

Como alternativa, você pode instalar e usar mmv

$ mmv -n '* - *.pdf' '#2 - #1.pdf'
abcdef - ghijkl.pdf -> ghijkl - abcdef.pdf

(Em todos os casos, remova o -n para concluir a operação).

    
por 06.02.2017 / 03:26
4

Usando o bash:

[[ $f =~ ^([^-]+)\ -\ ([^\.]+)\.(.*) ]] && 
  mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"

Isso usa o operador de teste regex do bash =~ para ver se o nome do arquivo dado (em $f ) corresponde ao padrão: "nada, exceto traço, seguido por espaço traço, seguido por qualquer coisa, exceto um ponto, seguido por um ponto , seguido de qualquer coisa ou nada ". Se o nome do arquivo corresponder a esse padrão, os bits correspondentes das subseções entre parênteses da regex serão atribuídos a elementos da matriz BASH_REMATCH.

Para fazer isso para todos os arquivos em uma pasta específica:

cd /to/that/folder
for f in *
do
  [ -f "$f" ] || continue
  [[ $f =~ ^([^-]+)\ -\ ([^\.]+)\.(.*) ]] && 
    mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"
done

Usando apenas expansões de variáveis especificadas por POSIX :

pre=${f%%.*}
ext=${f##*.}
mv "$f" "${pre##*- } - ${pre%% -*}.$ext"
    
por 06.02.2017 / 03:05
0

Você pode criar o script com esse comando:

\ls *-*.pdf | sed 's/\(.*\)-\(.*\).pdf/mv -.pdf -.pdf/' > script_mv.bash

Então você verifica se o script está correto, então você pode executá-lo:

. ./script_mv.bash

Eu escrevi \ ls, porque cancela opções em ls.

O padrão sed significa:

  • encontre qualquer coisa1, um "-", qualquer coisa2, ".pdf".
  • Ambas as coisas são colocadas em () para que elas obtenham os nomes \ 1 e \ 2.
  • então eu copio a linha mv, para isso eu posso recriar nomes de arquivos graças a \ 1 e \ 2.
por 05.02.2017 / 23:13
0

Resposta básica, específica para o padrão de nome "xxx - yyyy.ddd".

find -type f | while read flnm ; do basename "$flnm" | awk -F'[\ .]' '{print $3 " " $2 " " $1 "."$4}'; done

Encontre um arquivo e entregue o nome para um loop de leitura. Lá, use o basename para extrair o nome e entregá-lo ao Awk. Awk, usando vários separadores de campo, espaço e período, depois reimprime os campos, na ordem desejada.

abcdef - ghijkl.pdf

torna-se

ghijkl - abcdef.pdf

aplicação prática ... renomear arquivos para este novo nome padrão

find -type f | while read flnm ; do mv "$(basename "$flnm")"  "$(basename "$flnm" | awk -F'[\ .]' '{print $3 " " $2 " " $1 "."$4}')"; done

A única diferença é a inclusão do comando mv e o agrupamento dos nomes como strings.

    
por 06.02.2017 / 03:35