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.