Como posso renomear um arquivo no unix usando caracteres no nome do arquivo?

1

Eu tenho um monte de arquivos em um diretório unix que se parece com o seguinte:

filename_1234567.txt

Eu preciso renomeá-los copiando os três últimos caracteres de cada nome de arquivo para a frente do nome do arquivo assim:

567_filename_1234567.txt

NOTA: A extensão e o nome do arquivo são variáveis.

Estou executando isso em uma caixa do Solaris.

    
por Blair C 12.11.2015 / 20:49

5 respostas

3

com zsh :

autoload zmv
zmv -n '*(???).*' '$1_$f'

Remova -n quando estiver feliz.

    
por 12.11.2015 / 22:45
2

Então você deseja preceder os três últimos caracteres do nome da base do arquivo, seguidos por um sublinhado, na frente do nome do arquivo?

#!/bin/bash
EXT=.txt
for file in *${EXT}; do # presuming all the filenames have no spaces 
   base=${file%${EXT}}
   prefix=${base:(-3)}
   newname=${prefix}_${base}${EXT}
   mv ${file} ${newname}
done

Isso não funcionará no shell Korn, pois os truques usados são bash -specific:

ksh[3]: prefix=${base:(-3)}: bad substitution
por 12.11.2015 / 20:55
1

Eu gosto de fazer algo assim:

#!/bin/sh
for i in filename_*.txt; do echo "$i"; done |
sed "s/filename_\([0-9]*\)\([0-9]\{3\}\)\.txt/mv -i 'filename_.txt' '_filename_.txt'/g"

Isto imprime a lista de comandos mv para realizar a tarefa. Se ele imprimir os comandos corretos, basta anexar | sh no final do comando sed para fazer com que o shell os execute.

Este script usa o comando sed subsitute s e o recurso de referência anterior para usar partes da expressão regular correspondente na sequência de substituição.

s/regex/replacement/

As partes do padrão de expressão regular entre \( e \) podem ser referenciadas na sequência de substituição por \N , em que in é um número.

    
por 12.11.2015 / 22:33
1

Você está no Solaris, então você terá perl . Você pode até ter rename (ou possivelmente prename ):

rename -n 's/^(.*)(.{3})(\.[^.]*)$/$2_$1$2$3/' *.*

Remova -n ou altere para -v quando estiver pronto para rolar.

    
por 13.11.2015 / 00:42
1

Pure awk solution: a ideia básica é extrair os últimos 3 caracteres do nome base, o que significa um formulário de substring length - 6 (6 porque precisa considerar a extensão .txt ) para length - 3 . Aqui, eu apenas extraio essa substring para o VAR primeiro e, em seguida, crie o comando complete com mv e dois nomes de arquivos a serem executados; finalmente peço a função system para executar o comando.

Código:

awk 'BEGIN{
           VAR=sprintf("%s",substr(ARGV[1],length(ARGV[1])-6,3)); 
           CMD=("mv "ARGV[1]" "VAR"_"ARGV[1]); 
           print CMD; 
           system(CMD); 
           close(CMD)
          }' filename_1234567.txt 

Demo:

$ awk 'BEGIN{VAR=sprintf("%s",substr(ARGV[1],length(ARGV[1])-6,3)); CMD=("mv "ARGV[1]" "VAR"_"ARGV[1]); print CMD; system(CMD); close(CMD)}' filename_1234567.txt 
mv filename_1234567.txt 567_filename_1234567.txt
$ ls filename_1234567.txt
ls: cannot access filename_1234567.txt: No such file or directory
$ ls 567_filename_1234567.txt
567_filename_1234567.txt
$ 
    
por 14.11.2015 / 23:48