Rinominare file in blocco


25

Ho un numero di file:

10.3.100.179_01_20161018_230014_5335.jpg
10.3.100.179_01_20161018_231514_0814.jpg
10.3.100.179_01_20161018_233014_5706.jpg
10.3.100.179_01_20161018_234514_0896.jpg
10.3.100.179_01_20161018_230114_5395.jpg
10.3.100.179_01_20161018_231614_1145.jpg
10.3.100.179_01_20161018_233114_6047.jpg
10.3.100.179_01_20161018_234614_0547.jpg
10.3.100.179_01_20161018_230114_5492.jpg
10.3.100.179_01_20161018_231614_1264.jpg
10.3.100.179_01_20161018_233114_6146.jpg
10.3.100.179_01_20161018_234614_0658.jpg
10.3.100.179_01_20161018_230214_5630.jpg
10.3.100.179_01_20161018_231714_7135.jpg

Voglio rinominare con questo formato:

10.4.100.135_01_20161013131108389_TIMING.jpg
10.4.100.135_01_20161013131111390_TIMING.jpg
10.4.100.135_01_20161013131114401_TIMING.jpg
10.4.100.135_01_20161013131117431_TIMING.jpg
10.4.100.135_01_20161013131120418_TIMING.jpg
10.4.100.135_01_20161013131123461_TIMING.jpg
10.4.100.135_01_20161013131126511_TIMING.jpg

Deve rimuovere il _timestamp in e aggiungere il _TIMING.



5
Si prega di utilizzare esempi coerenti nelle vostre domande. Sembra che tu voglia sostituire 10.3.100.179con 10.4.100.135. È quello che vuoi o vuoi solo rimuovere il _TIMINGe il _dal tempo?
terdon,

3
Un buon momento per ricordare alle persone che esiste uno standard iso8601 per le date (che funziona sia per i nomi di file che per le voci di registro) ^^ Quindi forse dovresti riconsiderare la ridenominazione per diventare: AAAA-MM-GGThh: mm: ss.mmm (ex : il tuo primo file diventerebbe: 10.4.100.135_01_2016-10-13T13:11:08.389_TIMING.jpg(e "TIMING" potrebbe anche essere rimosso, dato che ora appare chiaramente come una data e un'ora (e millisecondi), specialmente quando lo standard diventa più diffuso. La T fa parte dello standard e io cresciuto per piacere (e tirarlo fuori rompe lo standard ^^)
Olivier Dulac,

@OlivierDulac Non consiglierei di usarlo :in un nome file. Credo che Windows non lo supporti.
Giustino,

@Justin buon punto. lo standard raccomanda di lasciarlo cadere per i nomi dei file. Ho dato la versione in-file
Olivier Dulac il

Risposte:


38

Installa renameutilse utilizza qmvcon il tuo editor di testo preferito.

qmvcarica tutti i nomi nel tuo editor e quando lo salvi e chiudi applica le tue modifiche ai file effettivi. Se le modifiche sono incoerenti (ad es. Due file hanno lo stesso nome) si interromperanno senza toccare nulla. Gestisce anche correttamente i nomi circolari.

Di solito faccio:

$ qmv -f do

in modo che mostri solo una colonna di nomi (do: solo destinazione). Ecco come appare:

qmw

Se lo combini con i cursori multipli di SublimeText, Atom o Visual Studio Code, è uno strumento molto utile e potente per rinominare in blocco. Ad esempio, per Atom, lo faresti EDITOR="atom -w" qmv -f do.


1
Benvenuto su askUbuntu! Questo è veramente forte!
αғsнιη,

Firmato solo per +! esso. ;)
J. Allan,

2
Caspita, bel strumento e bella animazione GIF. Ottima prima risposta, benvenuto! :)
Byte Commander

1
Grazie @KasiyA per aver incorporato l'immagine e grazie a tutti gli altri per i commenti positivi.
ateijelo,

1
@kasperd Sì, avviserà che il piano di ridenominazione contiene errori e aprirà una console interattiva in cui è possibile eseguire ulteriori azioni.
ateijelo,

27

Usa rename...

rename -n 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *

In -nquesto modo verrà visualizzato ciò che sta per fare senza apportare modifiche:

rename(10.3.100.179_01_20161018_230014_5335.jpg, 10.3.100.179_01_201610182300145335_TIMING.jpg)
rename(10.3.100.179_01_20161018_231514_0814.jpg, 10.3.100.179_01_201610182315140814_TIMING.jpg)
rename(10.3.100.179_01_20161018_233014_5706.jpg, 10.3.100.179_01_201610182330145706_TIMING.jpg)
rename(10.3.100.179_01_20161018_234514_0896.jpg, 10.3.100.179_01_201610182345140896_TIMING.jpg)

Se sembra corretto, rimuovere il -n

$ rename 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *
$ ls
10.3.100.179_01_201610182300145335_TIMING.jpg  10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_201610182315140814_TIMING.jpg  10.3.100.179_01_201610182345140896_TIMING.jpg

Spiegando ...

  • s/something/something_else/ cerca e sostituisci
  • ^ l'inizio del nome (ancoraggio)
  • [0-9] qualsiasi numero
  • + uno o più dei personaggi precedenti
  • \.letterale .(senza che \questo corrisponda a nessun personaggio)
  • () per mantenere questa parte
  • $1$2$3$3 indietro riferimenti alle cose abbinate in precedenza e mantenute con ()

Nota: *alla fine del comando corrisponde a tutti i file visibili nella directory corrente. Utilizzare un glob più adatto, se necessario.


2
In alcune distro, questo comando è disponibile come prename(p per perl, perché il primo argomento è un'espressione perl)
Peter Cordes,

12

mmv può farlo come nel seguente:

mmv '*_*_*_*_*.jpg' '#1_#2_#3#4#5_TIMING.jpg'

10.3.100.179_01_20161018_230014_5335.jpg 10.3.100.179_01_201610182300145335_TIMING.jpg

# 1, # 2, # 3, ... fa riferimento ciascuno al corrispondente '*' qui.

È ancora più breve con:

mmv '*_*_*.jpg' '#1#2#3_TIMING.jpg'

9

Un altro renameapproccio:

$ rename -n 's/(.*)_(.*)_(.*)\./$1$2$3_TIMING./' *
10.3.100.179_01_20161018_230014_5335.jpg -> 10.3.100.179_01_201610182300145335_TIMING.jpg
10.3.100.179_01_20161018_230114_5395.jpg -> 10.3.100.179_01_201610182301145395_TIMING.jpg
10.3.100.179_01_20161018_230114_5492.jpg -> 10.3.100.179_01_201610182301145492_TIMING.jpg
10.3.100.179_01_20161018_230214_5630.jpg -> 10.3.100.179_01_201610182302145630_TIMING.jpg
10.3.100.179_01_20161018_231514_0814.jpg -> 10.3.100.179_01_201610182315140814_TIMING.jpg
10.3.100.179_01_20161018_231614_1145.jpg -> 10.3.100.179_01_201610182316141145_TIMING.jpg
10.3.100.179_01_20161018_231614_1264.jpg -> 10.3.100.179_01_201610182316141264_TIMING.jpg
10.3.100.179_01_20161018_231714_7135.jpg -> 10.3.100.179_01_201610182317147135_TIMING.jpg
10.3.100.179_01_20161018_233014_5706.jpg -> 10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_20161018_233114_6047.jpg -> 10.3.100.179_01_201610182331146047_TIMING.jpg
10.3.100.179_01_20161018_233114_6146.jpg -> 10.3.100.179_01_201610182331146146_TIMING.jpg
10.3.100.179_01_20161018_234514_0896.jpg -> 10.3.100.179_01_201610182345140896_TIMING.jpg
10.3.100.179_01_20161018_234614_0547.jpg -> 10.3.100.179_01_201610182346140547_TIMING.jpg
10.3.100.179_01_20161018_234614_0658.jpg -> 10.3.100.179_01_201610182346140658_TIMING.jpg

Se sembra funzionare come vuoi, rimuovi il file -n.


5

È inoltre possibile utilizzare quanto segue. Prima fai un backup dei tuoi file e prova questo:

find . -name "*.jpg" -type f -print0| while read -d $'\0' file
do
    #extension="${file##*.}"
    newfilename=$(echo "${file%.*}" | sed 's/\(.*\)_\(.*\)_/\1\2/')
    mv "$file" "$newfilename""_TIMING.jpg"
done

sed 's/\(.*\)_\(.*\)_/\1\2/')elimina i _caratteri nel timestamp.

Per esempio:

user@host$ ls -lart
total 8
drwxrwxr-x 6 user user 4096 Oct 21 10:21 ..
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230014_5335.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231514_0814.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233014_5706.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234514_0896.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230114_5395.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231614_1145.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233114_6047.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234614_0547.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230114_5492.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231614_1264.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233114_6146.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234614_0658.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230214_5630.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231714_7135.jpg
drwxrwxr-x 2 user user 4096 Oct 21 10:30 .

user@host$ find . -name "*.jpg" -type f -print0 | while read -d $'\0' file
> do
>  newfilename=$(echo "${file%.*}" | sed 's/\(.*\)_\(.*\)_/\1\2/')
>  mv $file $newfilename"_TIMING.jpg"
> done

10:35:20 t $ ls -lart
total 8
drwxrwxr-x 6 user user 4096 Oct 21 10:21 ..
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182300145335_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182315140814_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182330145706_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182345140896_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182301145395_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182316141145_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182331146047_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182346140547_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182301145492_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182316141264_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182331146146_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182346140658_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182302145630_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182317147135_TIMING.jpg
drwxrwxr-x 2 user user 4096 Oct 21 10:35 .

1
questa è la soluzione migliore. Ovviamente, l'anima di Zanna è perfetta per un paio di file, ma poiché la shell viene eseguita dal globbing, la loro soluzione potrebbe fallire su un gran numero di file (stringa di comando troppo lunga).
rexkogitans,

@rexkogitans: se utilizzi un moderno sistema Linux (ovvero qualsiasi versione di Ubuntu), il limite sulla lunghezza della riga di comando è di più megabyte. E se si tratta di un problema, è possibile utilizzare find -maxdepth 1 -exec rename ... {} +per raggruppare l'elenco della directory corrente sulla riga di comando di rinomina. (aggiungi -name *.jpgo quello che vuoi). Ciò verrà eseguito molto più velocemente di un loop di shell che esegue il fork + exec sede mvper ogni nome di file, invece di rinominare una chiamata di sistema. (Potresti sbarazzarti seddell'uso della roba regex integrata di bash, ma il fork mvè ancora lento.)
Peter Cordes,

2

Probabilmente hai finito, ma ecco una (semplice) bashsoluzione completa: la
"soluzione semplice ... bash" è un ossimoro?

#!/bin/bash

#loop through all files ending in .jpg
for f in *.jpg;
do

    #cut out everything to the timestamp
    firsthalf=${f%_*_*_*}

    #get from the timestamp on
    lasthalf=${f#*_*_}

    #remove (all) underscores from timestamp
    #note the 2 forward slashes...
    lasthalf=${lasthalf//_/}

    #get our extension
    ext=${lasthalf##*.}

    #now we can remove the extension
    lasthalf=${lasthalf%.*}

    #rename the file
    #change `mv` to `echo` if you want to do a trial run first...
    mv "$f" "${firsthalf}_${lasthalf}_TIMING.${ext}"

done;

PS: la logica nel loop è stata testata con uno dei tuoi nomi di file di esempio. È passato.


1
Probabilmente è meglio usare un regex bash [[ $f ~= (.*)_(.*)_(.*)_(.*)\.jpg ]]; newname=${BASH_REMATCH[1]${BASH_REMATCH:2:4}TIMING.jpgo qualcosa del genere. (totalmente non testato e probabilmente sbagliato, ma l'idea generale è che i gruppi di acquisizione entrino nell'array BASH_REMATCH.)
Peter Cordes,

@PeterCordes: questo è un buon punto! Non ho mai usato ( bash) catturare gruppi e, ad essere sincero, bash non è la prima lingua con cui li proverei. (Penso che bashsia un linguaggio brutto.) Tuttavia, è una buona soluzione e mi ha insegnato qualcosa di così complimenti.
J. Allan,

Sì, il motivo principale per eseguire una tale elaborazione del testo in puro bash è quando si scrivono funzioni di completamento delle schede che dovrebbero essere veloci. Porta un significato completamente nuovo alla frase "brutto codice" ...
Peter Cordes,

@PeterCordes: Ho ottenere risultati, anche se io non credo che il codice è "brutto". Potrebbe non essere la soluzione a 2 righe che hai fornito, ma non è difficile da leggere per quanto mi riguarda; inoltre è ben commentato ...
J. Allan,

Stavo parlando del codice di completamento della bash in generale che è brutto (o almeno difficile da leggere). In realtà non è davvero brutto, solo un po 'strabiliante (ad esempio passare args per ref in bash fatto passando un nome di variabile e avere il comando call printf -v "$3" ...per impostare la variabile di cui è il nome $3.) Smontare l'intera riga di comando e rimetterla insieme è piuttosto difficile da seguire / debug, almeno l'ho trovato in quel modo mentre cercavo di ripulirlo / correggere bug. Vedi il codice su github
Peter Cordes,

1

Se potessi usare la GUI, consiglierei pyRenamer .

È presente nella maggior parte delle distribuzioni, fi in Ubuntu:

sudo apt-get install pyrenamer

Può fare tutto ciò che vuoi e altro ancora.

  • Può usare modelli, aggiungere o sopprimere il testo.
  • Può accedere ai dati EXIF ​​se rinomina le foto, quindi puoi generare modelli basati su data / ora, ecc ...
  • Può utilizzare alcuni metadati se rinomina i file musicali.
  • Inoltre, ha un'anteprima , che può impedire alcuni errori difficili da ripristinare.

Al downvoter ... Ti interessa spiegare perché? OP non ha specificato se la GUI fosse un'opzione o meno. Vedo che la maggior parte delle risposte va al modo console / script, ma molti utenti apprezzeranno una soluzione GUI. O forse pyRenamer ha qualche difetto di cui non sono a conoscenza. In ogni caso, mi piace conoscere i motivi dei voti negativi.
jrierab,

Potrei anche suggerire Thunar Bulk Renamer per un approccio GUI interattivo scattante.
Tony Martin,

@TonyMartin Questo dovrebbe essere un commento in questione, questo non ha nulla a che fare con la risposta
Sergiy Kolodyazhnyy,

0

Ecco il tuo raw + + + oneliner incorporato (love oneliners):findxargssedmv

find . -name "*.jpg" -print0 | sort -z | xargs -0 sh -c 'for filename; do mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g"); done' sh

Spiegazione:

  • find . -name "*.jpg" | sort | xargs sh -c <command> sh : elenca tutti i JPEG nella directory corrente, quindi esegui un comando shell per ognuno (l'ordinamento è facoltativo, ovviamente, ma mantieni le cose un po 'più pulite se stai registrando da qualche parte)

  • -print0, -z, -0: È buona abitudine di elementi separati con binario 0quando creazione di token nomi dei file per evitare problemi con in-the-middle bianco-spazi (non è il tuo caso, però)

  • mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g");: (le barre rovesciate nel sedregex non ne aiutano la leggibilità, ma è semplice) rinominare ogni file sostituendo la sequenza separata da sottolineatura di 8 + 6 + 4 cifre con la loro concatenazione contigua più questa _TIMINGcosa ( \iè un riferimento a i- th regex group).


Rif : Xargs - man sed

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.