perl rename: pré-adicionando algo a um conjunto de nomes de arquivos em subdiretórios

1

Embora a ferramenta perl rename tenha se tornado uma companheira inestimável para meu trabalho diário, ainda existem algumas peculiaridades que dificultam o trabalho - especialmente quando os arquivos não estão no diretório de trabalho atual .

Vamos supor que há muitas faturas e sabemos que todas do customer1 já estão atribuídas a uma conta. Assim, para facilitar o processamento de scripts mais tarde, queremos acrescentar antes assi_ para "atribuído".

Por exemplo:

/home/user/bizz/invoices $ ls -1 t1/inv*

t1/inv_customer1_20130506.txt
t1/inv_customer1_20130823.txt
t1/inv_customer1_20130930.txt
t1/inv_customer2_20131207.txt
t1/inv_customer2_20131113.txt

Agora veja o que vai acontecer:

/home/user/bizz/invoices $ rename 's/^/assi_/' t1/inv_customer1*

Can't rename t1/inv_customer1_20130506.txt assi_t1/inv_customer1_20130506.txt: No such file or directory
(etc.)

Heheh. rename escolheu o caminho completo para adicionar assi_ , em vez de apenas o arquivo. Portanto, não é de admirar que não encontre inv_customer1_20130506.txt no diretório não existente "assi_t1".

Então, como rename pode ser ensinado a aplicar a expressão regular apenas ao nome do arquivo?

Notas:
1. Nem sempre quero cd para os subdiretórios.
2. Eu evitaria usar loops, assim como find , se possível.

    
por syntaxerror 08.11.2014 / 22:43

1 resposta

2

rename funciona dessa maneira porque pode mover arquivos entre diretórios. Como mv , ele age em todo o caminho, não apenas no último componente.

Se você quiser modificar somente o último componente, poderá ancorar seu regexp em (\A|?<=/) e garantir que ele não corresponda a nenhum / e que corresponda apenas ao último / .

rename 's~(\A|?<=/)(?=[^/]*)\z~assi_~' t1/inv_customer1*

Outra abordagem é primeiro dividir o nome do arquivo.

rename 's~(.*/)~~s; my $d = $1; s/\A/assi_/; $_ = "$d$_"' t1/inv_customer1*

Você também pode usar o módulo File::Spec . Isso tem a vantagem de lidar com caminhos não-Unix.

rename 'use File::Spec::Functions; my ($v,$d,$f) = splitpath($_); $f =~ s/\A/assi_/; $_ = catpath($v,$d,$f)' t1/inv_customer1*
    
por 09.11.2014 / 01:19