Come rinominare più file in sequenza dalla riga di comando?


15

Come rinominare il file come di seguito

AS1100801000002.RAW7AGS 
AS1100801001008.RAW7AH4
AS1100801002001.RAW7AH9
AS1100801003002.RAW7AHE
AS1100801004009.RAW7AHT
AS1100801005002.RAW7AHY
AS1100801010002.RAW7AJ3

al nuovo nome

AS1.txt
AS2.txt
AS3.txt
AS4.txt
AS5.txt
AS6.txt
AS7.txt

Risposte:


22

Lo renamestrumento 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 -nper 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.


4

Non conosco un singolo comando o utilità che lo farebbe, ma è abbastanza facile da fare con un semplice ciclo:

N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done

3

Per migliorare @ di Oli risposta , lo renamestrumento 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,

  1. brew install renameoppure Scarica lo script
  2. Salvalo in una directory sul tuo percorso di sistema (di solito /usr/local/bin/brewo /usr/bin)

3
Questo sembra essere uno strumento diverso con lo stesso nome. L'impostazione predefinita di Ubuntu renameè prename. Questo potrebbe essere migliore ma potresti voler aggiungere istruzioni di installazione per rendere questa risposta più preziosa.
Oli

1
@Oli buona chiamata! aggiornato.
Atav32,

2

renameti consente di assegnare direttamente a $_, che è l'ideale per questo problema.

Anche se gli argomenti di codice si passa al Perl renameutility 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. renameti 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' -nopzione. 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 -nquando ti piace quello che vedi.

Se vuoi riempire con una larghezza maggiore di 2, sostituisci 2con un numero più grande. Ad esempio, se per qualche motivo volessi nomi di file simili AS00000000000001.txt, lo sostituiresti %02dcon %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 %02dcon just %d.

Come funziona? La shell si espande * in un elenco di file prima ancora di eseguire il renamecomando. L'elenco è ordinato lessicograficamente (ovvero in ordine alfabetico) in base alle impostazioni internazionali correnti. renamericeve i nomi dei file come argomenti della riga di comando e li elabora nell'ordine in cui sono elencati. L'espressione ++$ivaluta una maggiore del valore corrente della variabile $ie imposta anche la variabile $isu 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 renamefile di processo nell'ordine in cui vengono passati come argomenti, vengono numerati di conseguenza.


Potresti aver notato la somiglianza con la risposta di Oli !

Sia dichiarano che incrementano una variabile contatore, ed entrambi usano sprintfessenzialmente 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 /ein quel comando è ora la stessa dell'espressione che assegno $_(cioè il codice sul lato destro =dell'operatore) nel primo comando in questa risposta.

  • L' 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 sdell'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.
  • Quindi produce testo da ogni corrispondenza, ovvero da ogni intero nome file, costituito da 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.
  • Normalmente il testo sostituito our $i; sprintf "AS%02d.txt", ++$iverrebbe utilizzato come nome file, non eseguito come codice. Ma il /eflag 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 sprintffunzione 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/ /ecomandi. 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 sbandiera, che va alla fine (con e). Cioè, scrivi /sealla fine invece di /e.


0

Supponiamo che siano presenti i file che vuoi rinominare ~/Adire 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 ~/Adire 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 sortcomando è nel caso in cui si desideri che i file mantengano l'ordine iniziale.


0

Sebbene l'OP richieda un'opzione da riga di comando, è anche disponibile come opzione GUI in Nautilus ed è abbastanza semplice.

Selezionare tutti i file richiesti e premere F2. C'è un'opzione chiamata Numeri automatici. Puoi aggiungerlo al testo di cui hai bisogno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.