Rinomina file multipli usando lo scripting Bash

Voglio rinominare più file nella stessa directory usando lo scripting Bash. I nomi dei file sono i seguenti:

file2602201409853.p file0901201437404.p file0901201438761.p file1003201410069.p file2602201410180.p 

Desidero rinominare nel seguente formato:

file2503201409853.p file2503201437404.p file2503201438761.p file2503201410069.p file2503201410180.p 

Stavo leggendo del comando rename e ho provato a farlo in questo modo, ma non fa nulla, penso di avere domande sulla sintassi. Poi ho letto che puoi creare un ciclo utilizzando il comando mv come segue:

for file in cmpsms*2014*.p; do mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}" done 

Ma non riesco a rinominare i file. Cosa sto facendo di sbagliato?

Commenti

  • possibile duplicato di Come posso rinominare un lotto di file utilizzando unespressione regolare?
  • Non puoi ' avere unespressione di pattern sul lato destro di unespressione di sostituzione dellespansione di parametro. Cosa ti aspettavi che fosse dove si trova *?
  • @Kiwy Questa domanda riguarda la rimozione di una parte del nome del file. Ergo, altamente dubbio duplicato.
  • La prossima volta, descrivi le modifiche al nome del file che desideri apportare (ho dovuto guardarlo per un bel po prima di vedere le differenze e le somiglianze). Gli esempi sono buoni, ma una descrizione così come esempi è ancora migliore.

Risposta

Hai fatto bene a considerare prima la ridenominazione. La sintassi è un po strana se “non sei abituato alle espressioni regolari, ma è di gran lunga il percorso più veloce / breve una volta che sai cosa stai” facendo:

rename "s/\d{4}/2503/" file* 

Questo corrisponde semplicemente ai primi 4 numeri e li scambia con quelli che hai specificato.

E un test harness (-vn significa essere verboso ma non “t fare qualsiasi cosa) utilizzando i nomi dei file:

$ rename "s/\d{4}/2503/" file* -vn file0901201437404.p renamed as file2503201437404.p file0901201438761.p renamed as file2503201438761.p file1003201410069.p renamed as file2503201410069.p file2602201409853.p renamed as file2503201409853.p file2602201410180.p renamed as file2503201410180.p 

Commenti

  • Nota che questa è la rinomina Perl su Debian e derivati (Ubuntu, Mint, …). Su altre distribuzioni Linux, rename è uno strumento di ridenominazione di file completamente diverso (che Debian fornisce come rename.ul).
  • Se la tua mancanza distributiva di tale strumento, guarda la risposta di @Michael Campbell. Penso che ogni distribuzione sostituisca il valore predefinito rename come ha fatto Debian.

Risposta

Questo dovrebbe fare il trucco:

for f in file*; do mv $f ${f/${f:4:8}/25032014}; done 

Sostituisce la stringa tra il 4 ° e il 12 ° carattere con “25032014”.

Commenti

  • anche questo for f in file*; do mv $f ${f/${f:4:4}/2503}; done funziona.
  • Questo ' è carino. Se vuoi solo sostituire una parola per parola normale, funziona come sed. per esempio. for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
  • @Eric – Ho pubblicato la tua risposta come alternativa perché penso che ' sia più chiara ed elegante . Se vuoi pubblicarlo anche come risposta, ' elimino il mio. Grazie!
  • Perché virgolette doppie mancanti?
  • Mi dà un errore: " mv: target ' FILE_NAME ' non è una directory "

Risposta

questa è davvero la risposta di @Eric dallalto, ma è una risposta elegante quindi Lo ripubblico come una risposta adeguata per attirare più attenzione su di esso.

for f in *Huge*; do mv "$f" "${f/Huge/Monstrous}"; done 

Answer

ptrn="file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p" path=/dir ( set -- "${path}/"${ptrn} ; for f ; do { echo "mv ${path}/${f} \ ${path}/file25032014${f#2014}" } ; done ) 

Questo dovrebbe fare il trucco. Nota – Non sono abituato a consegnare comandi mv di massa – come scritto è” solo un eco. Tu ” dovrò risolverlo prima che “funzioni.

Risposta

Un modo semplice e nativo per farlo senza loop, con directory traversal :

find -type f | xargs -I {} mv {} {}.txt 

Rinominerà ogni file in posizione.

E sotto un lavoro esempio di ingaggio con parallelizzazione :

find -name "file*.p" | parallel "f="{}" ; mv -- {} ${f:0:4}2503${f:8}" 

Commenti

  • È stato un primo approccio facile per immaginare una soluzione migliore. Se vuoi un comando funzionante:
  • find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'

Rispondi

Se trovi che fai spesso questo genere di cose, cerca “rename.pl”. È “uno script Perl, ma ti permette semplicemente di alimentarlo con codice Perl (come /// espressione), e farà una ridenominazione di massa basata su quellespressione o codice.

Cè una versione base qui: http://stackoverflow.org/wiki/Rename.pl ma ci sono altre versioni che fluttuano nella rete. È in circolazione da secoli e secoli.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *