Script complesso per rinominare grandi quantità di file

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
King84

Script complesso per rinominare grandi quantità di file

Messaggio da King84 »

Ciao a tutti,
ho bisogno di rinominare grandi quantità di file e "pulire" il nome da alcuni tipi di caratteri, stringhe, etc...
Ho provato gprename ed è ottimo, ma voglio di più: creerò uno script!

Cosa voglio che faccia?
Sostanzialmente voglio che rinomini ricorsivamente tante cartelle e tanti file, seguendo alcune regole:
1) Eliminare da ogni nome alcuni caratteri singoli (ad esempio eliminare il carattere @)
2) Sostituire da ogni nome alcune stringhe con altre (ad esempio sostituire a ".jpeg" la stringa ".jpg")
3) Dalla cartella dove viene lanciato, deve entrare ricorsivamente dentro ogni sottocartella
4) Ovviamente non eliminare alcun file!

Non credo sia così impossibile da fare, ma siccome sono una capra a programmare, ho bisogno del vostro aiuto!
Ultima modifica di King84 il giovedì 22 novembre 2012, 12:56, modificato 1 volta in totale.
Avatar utente
maxbigsi
Tenace Tecnocrate
Tenace Tecnocrate
Messaggi: 17039
Iscrizione: mercoledì 21 maggio 2008, 14:05
Desktop: Xfce
Distribuzione: MX Linux 23.2 64bit
Sesso: Maschile
Contatti:

Re: Script complesso per rinominare grandi quantità di file

Messaggio da maxbigsi »

Ho provato gprename ed è ottimo, ma voglio di più: creerò uno script!
pensavo lo avresti creato tu :D
W il software libero..... W Ubuntu -- Ubuntu User # 31322
https://www.ergosumracalmuto.org/inform ... /index.php
King84

Re: Script complesso per rinominare grandi quantità di file

Messaggio da King84 »

Prendiamo solo il caso di file semplici di immagine

#!/bin/sh
for i in * *; do mv "$i" "${_}".jpg;
for i in *@*; do mv "$i" "${_}".jpg;
for i in *__*; do mv "$i" "${_}".jpg;
done

Ma sto ottenendo una marea di errori....Non sono capace! AIuto!
davide73
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 608
Iscrizione: giovedì 1 gennaio 2009, 17:17
Desktop: gnome
Distribuzione: Ubuntu 10.04.4 LTS i686
Località: Rimini

Re: Script complesso per rinominare grandi quantità di file

Messaggio da davide73 »

Intanto incomincia a fare una ricerca, di discussioni al proposito ne sono state aperte diverse, poi metti giù in maniera sintetica come pensi di attuare le azioni che hai citato nel tuo post in base anche a quali comandi bash vorresti usare(script in bash, giusto?).
ciao
ciao
Davide
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1183
Iscrizione: sabato 9 aprile 2011, 21:54
Desktop: KDE 4.8
Distribuzione: Gentoo ~amd64
Località: Torino

Re: Script complesso per rinominare grandi quantità di file

Messaggio da Laycastle »

Ecco a te:

Codice: Seleziona tutto

#!/bin/bash

#qua i simboli da eliminare
elimina=( "@" ";" ":" )

find $1 -type f -print | while read file ; do
  nwfile=${file##*/}
  path=${file%/*}
  for i in ${elimina[@]}; do
    nwfile="${nwfile//$i/}"
  done
  
  #sostituzioni
  nwfile="${nwfile// /_}"
  nwfile="${nwfile//.jpeg/.jpg}"
  
  mv "$file" "${path}/${nwfile}" 2>/dev/null
done
Imposta l'array "elimina" ai simboli/parole/frasi che desideri eliminare (ne ho messo qualcuno a caso :) ).
Dopo "sostituzioni" inserisci semplicemente ciò che vuoi sostituire, la formula è

Codice: Seleziona tutto

  nwfile="${nwfile//quello da sostituire/ciò da cui deve essere sostituito}"
Lo script si lancia passandogli come parametro la cartella su cui deve operare

Codice: Seleziona tutto

./script cartella
p.s. naturalmente declino ogni responsabilità, usatelo a vostro rischio e pericolo

Ciao.

EDIT: corretto lo script
Ultima modifica di Laycastle il sabato 30 giugno 2012, 12:31, modificato 1 volta in totale.
la via più breve tra due punti è l'arabesco.
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: Script complesso per rinominare grandi quantità di file

Messaggio da BlueEyes »

Lo script dovrebbe funzionare anche nel caso di semplice sostituzione di un carattere ... ma avrò sbagliato qualcosa, perché non succede nulla dopo l'avvio:

Codice: Seleziona tutto

#!/bin/bash
# ------------------------- Sostituire underscore con trattini ---------------------
dummy=()
find $1 -type f -print | while read file ; do
  nwfile="$file"
  for i in ${dummy}; do
    nwfile="${nwfile//$i/}"
  done
 
  nwfile="${nwfile// /_ /-}"
  mv "$file" "$nwfile" 2>/dev/null
done
Ciao
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1183
Iscrizione: sabato 9 aprile 2011, 21:54
Desktop: KDE 4.8
Distribuzione: Gentoo ~amd64
Località: Torino

Re: Script complesso per rinominare grandi quantità di file

Messaggio da Laycastle »

Codice: Seleziona tutto

nwfile="${nwfile//_ /-}"
non

Codice: Seleziona tutto

nwfile="${nwfile// /_ /-}"
:)

questo

Codice: Seleziona tutto

nwfile="${nwfile// /_}"
era per per sostituire gli spazi con un underscore. :)

Ciao.
la via più breve tra due punti è l'arabesco.
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1183
Iscrizione: sabato 9 aprile 2011, 21:54
Desktop: KDE 4.8
Distribuzione: Gentoo ~amd64
Località: Torino

Re: Script complesso per rinominare grandi quantità di file

Messaggio da Laycastle »

Mi sono accorto di un errore nello script, avrebbe creato problemi nel caso di cartelle contenenti caratteri da eliminare/sostituire.
Ho corretto sopra.
la via più breve tra due punti è l'arabesco.
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: Script complesso per rinominare grandi quantità di file

Messaggio da BlueEyes »

Ho corretto in conformità alle tue indicazioni ... ma ancora non va!
Ho cercato di allegare uno screenshot, invano. Larghezza > 800pxl, capienza superiore a... Boh??
Nuovo script:

Codice: Seleziona tutto

#!/bin/bash

dummy=()

find $1 -type f -print | while read file ; do
  nwfile=${file##*/}
  path=${file%/*}
  for i in ${dummy}; do
    nwfile="${nwfile//$i/}"
  done
  
  nwfile="${nwfile//_ /-}"
  mv "$file" "${path}/${nwfile}" 2>/dev/null
done
Ciao

EDIT: inserisco direttamente l'output

Codice: Seleziona tutto

~$ cd Scr*/zzz
~/Scrivania/zzz$ ls -l
totale 800
-rw-r--r-- 1 santino santino 605731 2011-11-17 15:00 Large_Deflection_of_DeepBeam_son_ElasticFoundations.pdf
-rw-r--r-- 1 santino santino 202736 2011-10-28 12:28 olive_nere.jpg
-rwxr-xr-x 1 santino santino    247 2012-06-30 12:41 rinom2.sh
-rw-r--r-- 1 santino santino    344 2012-06-30 12:35 rinom-base2.sh
santino@santino2:~/Scrivania/zzz$ ./rinom2.sh
santino@santino2:~/Scrivania/zzz$ ls -l
totale 800
-rw-r--r-- 1 santino santino 605731 2011-11-17 15:00 Large_Deflection_of_DeepBeam_son_ElasticFoundations.pdf
-rw-r--r-- 1 santino santino 202736 2011-10-28 12:28 olive_nere.jpg
-rwxr-xr-x 1 santino santino    247 2012-06-30 12:41 rinom2.sh
-rw-r--r-- 1 santino santino    344 2012-06-30 12:35 rinom-base2.sh
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1183
Iscrizione: sabato 9 aprile 2011, 21:54
Desktop: KDE 4.8
Distribuzione: Gentoo ~amd64
Località: Torino

Re: Script complesso per rinominare grandi quantità di file

Messaggio da Laycastle »

Ah, giusto, sta volta è colpa mia:

Codice: Seleziona tutto

nwfile="${nwfile//_/-}"
c'era uno spazio di troppo. :D
Come era prima cercava un underscore seguito da uno spazio.
la via più breve tra due punti è l'arabesco.
Avatar utente
BlueEyes
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1330
Iscrizione: giovedì 15 marzo 2012, 14:08

Re: Script complesso per rinominare grandi quantità di file

Messaggio da BlueEyes »

Ci siamo! :sisi: Ecco lo script finale:

Codice: Seleziona tutto

#!/bin/bash
# -------- Finale: sostituire underscore con trattini -------- 
dummy=()

find $1 -type f -print | while read file ; do
  nwfile=${file##*/}
  path=${file%/*}
  for i in ${dummy}; do
    nwfile="${nwfile//$i/}"
  done

  nwfile="${nwfile//_/-}"
  mv "$file" "${path}/${nwfile}" 2>/dev/null
done
Grazie
King84

Re: Script complesso per rinominare grandi quantità di file

Messaggio da King84 »

Ciao,
intanto GRAZIE per l'aiuto che mi state dando.
Il mio problema però è questo:
mi serve uno script che, lanciato da una cartella madre, operi le seguenti politiche anche all'interno di tutte le sottocartelle:
- se nel nome file c'è un carattere particolare come ad esempio "#", lo cancella (o lo sostituisce con "_")
- stessa cosa con altri caratteri particolari
- se nel nome file c'è una stringa tipo ".JPG", la sostituisce con ".jpg"
- stessa cosa con altre stringhe particolari
- tutto ciò anche ai nomi delle cartelle stesse

Con il vostro script non ottengo questi risultati, purtroppo
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1183
Iscrizione: sabato 9 aprile 2011, 21:54
Desktop: KDE 4.8
Distribuzione: Gentoo ~amd64
Località: Torino

Re: Script complesso per rinominare grandi quantità di file

Messaggio da Laycastle »

Ok, deve operare anche sulle directory dunque.

Codice: Seleziona tutto

#!/bin/bash

# qua i simboli da eliminare
elimina=( "@" ";" ":" )

move() {
  while read file ; do
    nwfile=${file##*/}
    path=${file%/*}
    for i in ${elimina[@]}; do
      nwfile="${nwfile//$i/}"
    done

  # Inserisci qua le tue sostituzioni:

    nwfile="${nwfile//-/_}"
    nwfile="${nwfile//.jpeg/.jpg}"

    mv -v "$file" "${path}/${nwfile}" 2>/dev/null
  done
}


find $1 -type d -print | move
find $1 -type f -print | move
manca ancora altro? :)

Ciao.
la via più breve tra due punti è l'arabesco.
King84

Re: Script complesso per rinominare grandi quantità di file

Messaggio da King84 »

Osta adesso cominciamo ad esserci decisamente..... Vi dovrò offrire una birra ragazzi.

Però avrei bisogno di alcune delucidazioni per modificarlo a mio piacere:

#!/bin/bash -> ok gli script cominciano così


# qua i simboli da eliminare
elimina=( "@" ";" ":" ) -> ok quindi metto tra virgolette, distanziati da uno spazio vuoto, i caratteri che voglio eliminare. Ma vale anche per stringhe? Cioè, se invece di "@" voglio eliminare "@@" oppure "abc", basta metterlo sempre così elimina=( "@" ";" ":" "@@" "abc") ?


move() {
while read file ; do
nwfile=${file##*/}
path=${file%/*}
for i in ${elimina[@]}; do
nwfile="${nwfile//$i/}"
done

--> tutto questo vale solo per la sostituzione di "@" ? Devo quindi ricopiarlo per ogni simbolo/stringa che voglio eliminare/modificare?

# Inserisci qua le tue sostituzioni:
nwfile="${nwfile//-/_}"
nwfile="${nwfile//.jpeg/.jpg}"

-> ok mi sostituisce "_" a "-" e di conseguenza ".jpg" a ".jpeg" e quindi se volessi fare altre sostituzioni basterebbe sempre fare nwfile="${nwfile//carattere_vecchio/carattere_nuovo}" ?

mv -v "$file" "${path}/${nwfile}" 2>/dev/null
done

a parte il done finale, non ho proprio capito che c'entra il 2>/dev/null
}


find $1 -type d -print | move
find $1 -type f -print | move

qui immagino che significhi "applica questo script di sostituzione sia se l'elemento letto è "-type d" quindi directory, sia "-type f" quindi file.
Sbaglio? Prende qualunque tipo di file (archivi, filmati, immagini, mp3, database, script, ...)?
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1183
Iscrizione: sabato 9 aprile 2011, 21:54
Desktop: KDE 4.8
Distribuzione: Gentoo ~amd64
Località: Torino

Re: Script complesso per rinominare grandi quantità di file

Messaggio da Laycastle »

King84 » [url=http://forum.ubuntu-it.org/viewtopic.php?p=4123180#p4123180]20 minuti fa[/url] ha scritto:

Codice: Seleziona tutto

# qua i simboli da eliminare
elimina=( "@" ";" ":" )
-> ok quindi metto tra virgolette, distanziati da uno spazio vuoto, i caratteri che voglio eliminare. Ma vale anche per stringhe? Cioè, se invece di "@" voglio eliminare "@@" oppure "abc", basta metterlo sempre così elimina=( "@" ";" ":" "@@" "abc") ?
Si, esatto. :)

Codice: Seleziona tutto

for i in ${elimina[@]}; do
nwfile="${nwfile//$i/}"
done
--> tutto questo vale solo per la sostituzione di "@" ? Devo quindi ricopiarlo per ogni simbolo/stringa che voglio eliminare/modificare?
No, non ce ne bisogno.
"elimina" è un array, ${elimina[@]} è il modo in cui si accede a tutti i suoi elementi

Codice: Seleziona tutto

laycastle ~ $ array=( "a" "b" "c" "abc" 1)
laycastle ~ $ echo $array
a
laycastle ~ $ echo ${array[@]}
a b c abc 1
laycastle ~ $ for i in ${array[@]}; do echo $i ;done
a
b
c
abc
1

Codice: Seleziona tutto

# Inserisci qua le tue sostituzioni:
nwfile="${nwfile//-/_}"
nwfile="${nwfile//.jpeg/.jpg}"
-> ok mi sostituisce "_" a "-" e di conseguenza ".jpg" a ".jpeg" e quindi se volessi fare altre sostituzioni basterebbe sempre fare nwfile="${nwfile//carattere_vecchio/carattere_nuovo}" ?
Si, l'avevo anche già scritto.
Laycastle ha scritto: la formula è

Codice: Seleziona tutto

  nwfile="${nwfile//quello da sostituire/ciò da cui deve essere sostituito}"

Codice: Seleziona tutto

mv -v "$file" "${path}/${nwfile}" 2>/dev/null
done
a parte il done finale, non ho proprio capito che c'entra il 2>/dev/null
Il 2>/dev/null serve per evitare di visualizzare i messaggi d'errore, che in questo caso sono per lo più inutili e sporcano solo l'output.

Codice: Seleziona tutto

find $1 -type d -print | move
find $1 -type f -print | move
qui immagino che significhi "applica questo script di sostituzione sia se l'elemento letto è "-type d" quindi directory, sia "-type f" quindi file.
Sbaglio?
Diciamo di si, find parte dalla directory specificata e passa come argomento rispettivamente le directory e i file regolari.
Non si poteva fare tutto con un unico find perché se rinomini una cartella cambia il percorso di tutti i file all'interno della stessa.
Prende qualunque tipo di file (archivi, filmati, immagini, mp3, database, script, ...)?
Si, su qualsiasi tipo di file regolare, non prende in considerazione device a blocchi, pipe ed altri tipi di file speciali, ma non credo interessino. :D

Ciao.
la via più breve tra due punti è l'arabesco.
MariusMatutiae
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1300
Iscrizione: martedì 3 luglio 2012, 14:46
Distribuzione: Debian, OpenBSD, Arch Linux
Località: Sanremo

Re: Script complesso per rinominare grandi quantità di file

Messaggio da MariusMatutiae »

Non credo che ci sia bisogno di uno script, si può usare il comando find, che scende
ricorsivamente dalla directory indicata., cercando files di un tipo speciale, e, per ogni
file trovato del tipo desiderato, esegue una operazione.

Si può inoltre usare il comando rename (che ha la sintassi di vi o perl per le sostituzioni), per
eseguire l'operazione desiderata.

Per esempio, per trovare tutti i files di tipo .jpeg, puoi digitare:

Codice: Seleziona tutto

find . -name '*.jpeg' -type f -exec rename 's/\.jpeg$//\.jpg$/' { } \;
Qui il comando find parte da . (la directory corrente) per cercare i files
(-type f) che hanno nel nome la sequenza di caratteri .jpeg (-name
'*.jpeg'). Quando ne ha trovato uno, esegue (-exec) il comando
rename, che sostituisce la stringa .jpegFINE PAROLA (FINE PAROLA
è il significato di $) con la stringa .jpgFINE PAROLA nel nome
appena trovato ({}).

E similmente per il resto.
Numquam latravit inepte
King84

Re: Script complesso per rinominare grandi quantità di file

Messaggio da King84 »

Preferisco utilizzare lo script, anche se ovviamente il comando "find" mi sembra molto potente a riguardo.
Bene, rimane ora solo l'ultimo problema: e se un file, rinominato, avesse lo stesso nome di un altro file già presente?

Esempio:
Nella cartella Folder ci sono i tre file
abc123.jpg
abc123!.jpg
abc123!_.jpg

Faccio partire lo script, toglie al primo file il punto interrogativo e che fa? Si blocca? Sovrascrive un file già esistente?
Vorrei far sì che, in caso di omonimia, quello che viene rinominato abbia aggiunto alla fine qualcosa, prima dell'estensione ".jpg", tipo "_doppio", cosicchè nella cartella Folder rimangano tutti i tre file
abc123.jpg
abc123_doppio.jpg
abc123_doppio_doppio.jpg

La cosa importante è che non venga sovrascritto alcun file
King84

Re: Script complesso per rinominare grandi quantità di file

Messaggio da King84 »

Quindi?
Io non saprei davvero da dove cominciare...
King84

Re: Script complesso per rinominare grandi quantità di file

Messaggio da King84 »

Qualcuno mi sa dire come far sì che lo script creato da Laycastle aggiunga qualcosa al noime dei file rinominati, così da non sovrascrivere un file precedentemente già esistente?
King84

Re: Script complesso per rinominare grandi quantità di file

Messaggio da King84 »

Qualche novità?
A qualcuno è venuto in mente qualcosa?
Io sono fermo al punto di partenza, ossia al 28/06
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 7 ospiti