2009-12-02 16 views
5

Ho un sacco di file che sto cercando di cambiare titolo, ho cercato di fare un'espressione regolare per corrispondere loro, ma anche questo mi sono bloccato sui file sono denominati come:Come posso rinominare facilmente i file con Perl?

Nome file 01

Nome file 100

Nome file 02

File Nome 03

etc, vorrei un dd uno "0" (zero), dietro a uno qualsiasi dei file sono meno di 100, come questo:

Nome file 001

Nome file 100

Nome file 002

File Nome 003

Il più vicino che ho ottenuto per abbinarli era usare questo tipo di ricerca d | ordina -r | grep '[1-9] [0-9] $' tuttavia non sono riuscito a capire come sostituirli. Grazie in anticipo per qualsiasi aiuto tu possa offrirmi. Sono su CentOS se questo è di qualche aiuto, tutto questo viene fatto tramite SSH.

+0

I vostri nomi dei file in realtà contengono spazi? –

+0

Sì, assomigliano a: "Nome file 01" "Nome file 101" –

+1

È possibile elaborare gli "strumenti" disponibili sulla macchina? Hai installato perl, pitone, rubino o simili? –

risposta

12
perl -e 'foreach $f (glob("File\\ Name*")) { $nf = $f; $nf =~ s/(\d+)$/sprintf("%03d",$1)/e; print `mv \"$f\" \"$nf\"`;}' 

Un po 'eccessivo forse, ma fa ciò che viene richiesto.

0

Penso che mmv sia tuo amico qui.

9
find . -type d -print0 | xargs -0 rename 's/(\d+)/sprintf "%03d", $1/e' 

o qualcosa di simile, a condizione

  1. Hai GNU trovare e GNU xargs (per -print0 e -0)
  2. avete la 'rinominare' programma di utilità che viene fornito con perl
  3. C'è solo un gruppo di cifre nel nome del file. Se ce n'è più di uno, allora devi fare qualcosa con la regex per farlo corrispondere solo al numero che vuoi riformattare.
+0

Questo è vicino a qualcosa che stavo per suggerire, usando sed invece di xargs, quindi lo farò +1. – shoover

+0

Sapevo che xargs era la strada da percorrere, non potevo scrivere il comando esatto. –

+0

+1 Per le dipendenze dell'elenco (è possibile che l'utilità di rinomina a cui ci si riferisce sia yum o apt-get away). – ChristopheD

2

Run due comandi, in questo ordine:

$ rename 's/File Name (\d)$/File Name 0$1/' * 
$ rename 's/File Name (\d\d)$/File Name 0$1/' * 

Primo uno rinomina tutto inferiore a 10 e anteporre uno zero. Il secondo rinomina tutto meno di 100 e antepone uno zero. Il risultato dovrebbe essere di tre cifre per tutti i nomi di file.

+0

In quale ambiente sono quei comandi validi? –

+0

'rename' è un'utilità fornita con la distribuzione standard perl. Ho eseguito questi sotto Linux Bash. –

+0

[Il simbolo $ dovrebbe rappresentare un prompt dei comandi.] –

0

si potrebbe fare qualcosa usando perl o rubino.

mettere tutto questo file nella stessa directory

dirlisting = DIR.entries('.') 

dirListing.each do |file| 
num = file.match(/\d+$/).to_i 
if num < 100 
    find the position where start the number, with index and inject the 0 there. 
end 
end 
+0

Probabilmente dovresti menzionare che questo codice è ruby ​​e non perl –

+0

se leggi la mia frase vedresti "perl OR ruby" –

+0

E questo è il motivo per cui ho detto che dovresti disambiguare Infatti il ​​codice è rubino. –

4

Si tratta di una cosa di una volta? In tal caso, suggerirò qualcosa che potrebbe sembrare un poliziotto da molti programmatori qui:

Immettere l'output del comando (find -type d | sort -r | grep ' [1-9][0-9]$') in un file e utilizzare un editor insieme a qualche ricerca/sostituzione globale magia per creare uno script che rinomina.

Quindi buttare via la sceneggiatura.

C'è poco chiasso e poche possibilità che finirai per spararti ai piedi facendo un tentativo di un intelligente (ma inadeguato debug) one-liner andare nelle erbacce dei tuoi file.

+0

++! A volte è meglio usare un kludge che capisci piuttosto che imparare "la magia profonda". – daotoad

+0

+1 Penso che questo genere di cose sia spesso la soluzione più pragmatica per i requisiti uno off –

+0

Potrebbe essere un cop-out, ma è un cop-out sicuro ... complimenti. –

0
use strict; 
use File::Copy; 

my @files = glob 'File*Name*'; 

foreach my $filename (@files) { 
    if ($filename =~ m`^.*File.*Name.*?(\d+)`) { 
     my $number = $1; 
     next if ($number > 99); 
     rename $filename, sprintf("FileName%03d",$number); 
    } 
} 
+0

Questo rinomina "Nome file 100" in "Nome file 0100" che non è destinato. –

+0

Avevi sicuramente ragione. Aggiunto del codice per farlo in modo che non accada. –

1

Nel mio debian funziona bene con rinomina, testato con 300 file.

perl -e 'map `touch door$_.txt`, 1..300;' 
rename 's/(\d+)\.txt/sprintf("%03d.txt", $1)/e' *.txt 
0

se il telecomando ha shell bash

for i in File*; 
do 
    case "${i##* }" in [0-9][0-9]) 
     echo mv "$i" "${i% *} $(printf "%03d" ${i##* })" ;; 
    esac; 
done 

Rimuovi "echo" fare ridenominazione attuale

Problemi correlati