Risposte:
Lo rename
strumento fornito con Ubuntu è piuttosto caldo in questo genere di cose. Puoi incorporare piccole espressioni Perl in questo modo:
rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *
Questo ti mostrerà solo cosa farebbe. Rimuovere il -n
per renderlo un esercizio di fuoco vivo.
Questo funziona fondamentalmente definendo approssimativamente una variabile e incrementandola ogni file che colpiamo. Se hai più di 10 file, ti suggerisco di usare un po 'di padding zero nel file sprintf
. Quanto segue è valido fino a 999
:
rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *
... Ma è abbastanza facile da espandere.
Per migliorare @ di Oli risposta , lo rename
strumento di versione 1.600 da Aristotele Pagaltzis ha in realtà un contatore integrato, $N
.
Quindi tutto ciò di cui hai bisogno è
rename 's/AS.*/AS$N/' *
Installare,
brew install rename
oppure Scarica lo script/usr/local/bin/brew
o /usr/bin
)rename
ti consente di assegnare direttamente a $_
, che è l'ideale per questo problema.Anche se gli argomenti di codice si passa al Perl rename
utility spesso eseguono corrispondenza e la sostituzione (con s/
), ed è del tutto accettabile per risolvere questo problema in questo modo , non c'è davvero alcun bisogno di che in casi come questo in cui non si è in realtà l'esame o riutilizzando il testo dei vecchi nomi di file. rename
ti consente di scrivere praticamente su qualsiasi codice Perl e non deve essere incorporato all'interno s/
/e
. Suggerisco di usare un comando come questo:
rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *
Oppure, se hai voglia di radere alcuni personaggi:
rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *
(Potrebbe essere reso ancora più breve, ma non senza sacrificare la chiarezza.)
Entrambi questi comandi fanno la stessa cosa. Ciascuno mostra quali operazioni di ridenominazione sarebbero state intraprese. Dopo averne provato uno e sei soddisfatto dei risultati, eseguilo di nuovo senza l' -n
opzione. Come scritto, ciò produrrebbe i nomi dei file AS01.txt
, AS02.txt
, ..., AS10.txt
, AS11.txt
, e così via. Puoi modificarli secondo necessità, quindi rimuoverli solo -n
quando ti piace quello che vedi.
Se vuoi riempire con una larghezza maggiore di 2, sostituisci 2
con un numero più grande. Ad esempio, se per qualche motivo volessi nomi di file simili AS00000000000001.txt
, lo sostituiresti %02d
con %014d
. Se non vuoi affatto riempire - anche se ciò farebbe apparire i tuoi file in ordine non numerico quando li elencherai in seguito! - allora puoi sostituirli %02d
con just %d
.
Come funziona? La shell si espande *
in un elenco di file prima ancora di eseguire il rename
comando. L'elenco è ordinato lessicograficamente (ovvero in ordine alfabetico) in base alle impostazioni internazionali correnti. rename
riceve i nomi dei file come argomenti della riga di comando e li elabora nell'ordine in cui sono elencati. L'espressione ++$i
valuta una maggiore del valore corrente della variabile $i
e imposta anche la variabile $i
su quel valore appena incrementato. Questo valore viene passato a sprintf
, che lo formatta e lo inserisce in altro testo. Questo testo viene assegnato direttamente alla variabile speciale $_
, che contiene il nome file. Poiché i rename
file di processo nell'ordine in cui vengono passati come argomenti, vengono numerati di conseguenza.
Sia dichiarano che incrementano una variabile contatore, ed entrambi usano sprintf
essenzialmente allo stesso modo per incorporare il valore di quel contatore, imbottito a sinistra con zeri, nell'altro testo dei nuovi nomi di file. (Le informazioni in entrambe le risposte su come riempire con gli zeri - e modificare la larghezza del riempimento - si applicano ugualmente a entrambi.) Il motivo per cui sono così simili è che il metodo in quella risposta più vecchia sta facendo proprio questo 1 , ma con passaggi aggiuntivi che sono utili per molti problemi ma non effettivamente necessari per questo.
Per fare un confronto, ecco come appare il secondo comando in quella risposta se modificato per usare lo stile che ho usato qui (e per passare a una larghezza di 2, come ho fatto qui, invece di 3):
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *
La parte tra s/.+/
e /e
in quel comando è ora la stessa dell'espressione che assegno $_
(cioè il codice sul lato destro =
dell'operatore) nel primo comando in questa risposta.
s/
operatore tenta di far corrispondere il testo (nomi di file che la shell ha espanso *
e passato come argomenti della riga di comando durante l'esecuzione rename
) con un'espressione regolare ed esegue la sostituzione. /
viene utilizzato come delimitatore per separare le diverse parti s
dell'espressione. La prima parte, .+
è l'espressione regolare; corrisponde ogni 1 carattere ( .
) , e lo fa una o più volte ( +
) . Dato che i nomi dei file non sono mai vuoti - sono sempre lunghi almeno un carattere - questo è un modo per abbinare 1 nome file.our $i; sprintf "AS%02d.txt", ++$i
. Questo produce il nuovo nome file. In genere, si usa s/
per produrre testo che sia (a) sostituendo il testo che corrisponde solo a una parte del nome del file, oppure (b) basato sul testo corrispondente in qualche modo (ad esempio, potrebbe utilizzare una variabile speciale come $&
quella che si espande in la partita). In questo caso, tuttavia, il testo corrispondente non viene utilizzato affatto.our $i; sprintf "AS%02d.txt", ++$i
verrebbe utilizzato come nome file, non eseguito come codice. Ma il /e
flag alla fine fa sì che quel testo sia trattato come codice sorgente Perl e valutato, e usa il valore prodotto facendo così (in questo caso, il valore di ritorno della sprintf
funzione integrata di Perl ) come nuovo nome file.Anche se penso che il metodo che ho mostrato qui sia un approccio più chiaro e più semplice per questo problema rispetto a qualsiasi metodo che utilizza s/
con /e
, è bene essere consapevoli di quella tecnica, perché è adatto a una serie di altri problemi di ridenominazione dei file in cui tutti o parte dei nomi dei file originali viene esaminata e / o conservata. Consiglio questo post sul blog di Oli (che ha anche scritto quella risposta ), che include alcuni di questi esempi.
1 Tecnicamente, non è una differenza nel comportamento dei $_ =
comandi e dei s/
/e
comandi. Nell'espressione regolare .+
, non è strettamente vero che .
corrisponde a qualsiasi carattere, perché non corrisponde a una nuova riga . Molto probabilmente non dovresti usare nomi di file con nuove righe, ma puoi, e occasionalmente un file viene nominato in quel modo per caso. Se ne hai voglia, contrapponi l'output di rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'
a quello di rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'
. Per .
abbinare una nuova riga, usa la s
bandiera, che va alla fine (con e
). Cioè, scrivi /se
alla fine invece di /e
.
Supponiamo che siano presenti i file che vuoi rinominare ~/Adir
e questi sono gli unici file in questa cartella, quindi:
n=0
for f in $( ls ~/Adir | sort ) ; do
n=$(( n+1 ))
mv -n "$f" "AS${n}.txt"
done
Questo script esaminerà ogni file ~/Adir
e lo rinominerà AS1.txt, AS2.txt, ...
se il file non esiste (non ci sarà alcuna sovrascrittura). Ecco perché dovresti assicurarti che questi siano gli unici file in ~/Adir
. Il sort
comando è nel caso in cui si desideri che i file mantengano l'ordine iniziale.
rename
è prename. Questo potrebbe essere migliore ma potresti voler aggiungere istruzioni di installazione per rendere questa risposta più preziosa.