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

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

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

<sobrenome>, <nome> <segundo nome>? - <descrição do projeto>

Por exemplo:

Miller, John Andrew - Descrição longa do projeto
Willis, Bruce - Descrição, talvez com vírgula
Lewis, Mary-Jane - Descrição - Incluindo menos

A nova convenção de nomenclatura é:

<primeiro nome> <segundo nome>? <sobrenome> - <descrição do projeto>

Por exemplo:

John Andrew Miller - Descrição longa do projeto
Bruce Willis – Descrição, talvez com vírgula
Mary-Jane Lewis - Descrição - Incluindo menos

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

Responder1

Como a parte de 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 quenãoocorrer na parte de 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 uma vírgula'. Como rename é ganancioso por padrão, ele corresponde à string mais longa possível.

O resto, eu acho, segue naturalmente.

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

printf '%s\n' *£*

Se você tiver renomeação perl:

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

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

Você deve testar isso com o -nsinalizador, que não renomeará nenhum arquivo, mas mostrará o que éseriafiz:

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

Responder2

No que diz respeito à correspondência, você precisa ter muito cuidado para construir algo robusto. Por exemplo, supondo que o nome e o nome 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 próprio se torna algo como [[:alpha:]][[:alpha:]-]*. Você pode então criar um nome do meio opcional separado por espaço, ((?: [[:alpha:]][[:alpha:]-]*)?)onde a estrutura extra do grupo sem captura apenas ajuda a manter os números do grupo de captura corretos quando o nome do meio está vazio. Reunindo tudo, 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/' *

O -nswitch é autônomo, ou seja, não executará as renomeações até ser removido. Se você não tiver a renomeação baseada em Perl, poderá usar uma combinação de perle mv.

informação relacionada