Como trocar palavras em um nome de arquivo usando o shell?

4

Um dos meus clientes é uma escola. Em seu servidor de arquivos, todos os projetos têm um diretório com o mesmo esquema de nomenclatura.

<last name>, <first name> <second name>? - <project description>

Por exemplo:

Miller, John Andrew - Long project description
Willis, Bruce - Description, perhaps with comma
Lewis, Mary-Jane - Description - Including minus

A nova convenção de nomenclatura é:

<first name> <second name>? <last name> - <project description>

Por exemplo:

John Andrew Miller - Long project description
Bruce Willis - Description, perhaps with comma
Mary-Jane Lewis - Description - Including minus

Agora, como renomear em lote todas as pastas existentes para a nova convenção?

    
por Philipp 05.10.2014 / 09:57

2 respostas

1

Como a parte da descrição do nome do arquivo pode conter o padrão - (um hífen entre dois espaços), você pode alterá-lo para algum símbolo que não ocorra na parte da descrição. Eu escolhi £ , mas isso é puramente arbitrário.

rename 's/ - /£/' *
rename 's/([^,]*), ([^£]*)£/$2 $1 - /' *

s/ - /£/' tells rename to replace the first instance of - it finds with £ . The second command is a bit more complicated. Parenthases ( () ) are used to group selections together -- so everything that matches the pattern within the first set of parens can be called later as $ 1 (all the way up to $ 9 ). [^,] means 'any character, except for , '; means 'zero or more of the previous character'; [^,] 'significa' zero ou mais de qualquer caractere, exceto por uma vírgula '. Como a renomeação é gulosa por padrão, ela corresponde à string mais longa possível.

O resto, penso eu, segue muito naturalmente.

Se você não tiver certeza se um símbolo aparece em algum lugar no nome do arquivo, basta executar:

printf '%s\n' *£*

Se você tiver perl-rename:

rename 's/([^,]*), (.*) - /$2 $1 - /' *

Isso será interrompido se a parte da descrição dos nomes de arquivos contiver - (ou seja, um - entre dois espaços).

Você deve testar isso com o sinal -n , que não renomeia nenhum arquivo, mas mostrará o que teria :

rename -n 's/([^,]*), (.*) - /$2 $1 - /' *
    
por 05.10.2014 / 10:25
0

No que diz respeito à correspondência, você precisa ter bastante cuidado para construir algo robusto. Por exemplo, assumindo que os nomes do primeiro e do meio

  1. deve começar com uma letra
  2. pode conter hífens (mas nenhuma outra pontuação ou espaço em branco)

seu padrão de nome dado se torna algo como [[:alpha:]][[:alpha:]-]* . É possível, então, criar um nome do meio separado por espaço como ((?: [[:alpha:]][[:alpha:]-]*)?) , em que a estrutura de grupo extra sem captura apenas ajuda a manter os números do grupo de captura retos quando o nome do meio está vazio. Juntando, por exemplo, usando o comando rename baseado em perl

rename -nv -- 's/(^[^,]*), ([[:alpha:]][[:alpha:]-]*)((?: [[:alpha:]][[:alpha:]-]*)?)/$2$3 $1/' *

ou (permitindo espaços em branco mais gerais entre os campos em vez de espaços únicos)

rename -nv -- 's/(^[^,]*),\s+([[:alpha:]][[:alpha:]-]*)((?:\s+[[:alpha:]][[:alpha:]-]*)?)/$2$3 $1/' *

A opção -n não funciona, ou seja, não executará as renomeações até ser removida. Se você não tiver a renomeação baseada em perl, poderá usar uma combinação de perl e mv .

    
por 05.10.2014 / 15:06