Newsgroup: it.comp.os.linux.sys
Titolo: oneliner per sostituire nomi file

Ciao,
Mettiamo il caso che ho dei file con degli spazi nei nomi, ed io voglia
cambiarne il nome, secondo una determinata regola, ma mantenendo gli spazi.
Es: pippo pluto.txt ==> paperino pluto.txt
Pensavo di usare questo oneliner, ma non funziona:
for i in * ; do mv -i `echo $i | sed 's/ /\\ /g'`\
`echo $i | sed -e 's/ /\\ /g' -e 's/pippo/paperino/g'`; done
g4b0@sun:~/tmp$ ls
pippo\ pluto.txt
g4b0@sun:~/tmp$ for i in * ; do mv -i `echo $i | sed 's/ /\\ /g'`\
`echo $i | sed -e 's/ /\\ /g' -e 's/pippo/paperino/g'`; done
mv: when moving multiple files, last argument must be a directory
Try `mv --help' for more information.
g4b0@sun:~/tmp$ echo $i | sed 's/ /\\ /g'
pippo\ pluto.txt
g4b0@sun:~/tmp$ echo $i | sed -e 's/ /\\ /g' -e 's/pippo/paperino/g'
paperino\ pluto.txt
g4b0@sun:~/tmp$       
Dove sbaglio?
-- 
g4b0, linux user n. 369000
http://gabo.homelinux.com

 cambiarne il nome, secondo una determinata regola, ma mantenendo gli spazi.
Usi rename.
-- 
Flavio Visentin
Scientists have finally discovered what's wrong with the female brain:
On the left side, there is nothing right, and on the right side, there
is nothing left.

 Usi rename.
Hai ragione, ci avevo anche pensato, perņ il mio č solo un esempio.. in
realtą ho bisogno di sostituire con delle regexp, ed il rename fornito da
slackware non me lo permette...


 `echo $i | sed -e 's/ /\\ /g' -e 's/pippo/paperino/g'`; done
Se vuoi cambiare fino al primo spazio, puoi fare
for i in *; do mv -i -- "$i" "paperino ${i#* }"; done
Suggerimento: fai un echo dei nomi prima per vedere che corrispondano a
quello che vorresti.
Se i file non cominciano tutti con "pippo ", allora bisogna fare un test per
rinominare solo i file che ti interessano (si allunga un po' lo script).

 Se vuoi cambiare fino al primo spazio, puoi fare
Nono, 
come ho detto a the_zipman il mio è solo un esempio, devo usare delle regexp
perchè il problema è decisamente più complesso, devo far funzionare lo
script di cui sopra..


 lo script di cui sopra..
Allora forse e' meglio se posti qualche esempio reale o comunque da cui si
possa ricavare piu' esattamente cosa vorresti fare...

 possa ricavare piu' esattamente cosa vorresti fare...
Il problema č che non mi fa l'escape degli spazi:
g4b0@sun:~/tmp$ echo mv -i `echo $i | sed 's/ /\\ /g'` \
`echo $i | sed -e 's/ /\\ /g' -e 's/pippo/paperino/g'`
mv -i pippo pluto.txt paperino pluto.txt
Mentre in questo caso me lo fa:
g4b0@sun:~/tmp$ echo $i | sed 's/ /\\ /g'
pippo\ pluto.txt
g4b0@sun:~/tmp$ echo $i | sed -e 's/ /\\ /g' -e 's/pippo/paperino/g'
paperino\ pluto.txt
Perchč?


g4b0 wrote:

Ci sono!! se faccio echo di qualcosa all'interno di `` mi viene rimosso il
carattere di escape. C'č qualche modo di evitare questo comportamento?


 Perchè?
Se proprio vuoi usare quell'approccio, devi quotare la sostituzione di
comando:
echo mv -i "$i" \
"`echo $i | sed 's/pippo/paperino/g'`"
ma imho e' un orrore che grida vendetta... :-)
 

 ma imho e' un orrore che grida vendetta... :-)
Non funziona :( ci avevo pensato pure io, e pure io avevo rabbrividito...
g4b0@sun:~/tmp$ echo mv -i "`echo $i | sed 's/ /\\ /g'`" "`echo $i |
sed -e 's/ /\\ /g' -e 's/pippo/paperino/g'`"
mv -i pippo pluto.txt paperino pluto.txt
g4b0@sun:~/tmp$ echo $i | sed 's/ /\\ /g'
pippo\ pluto.txt
g4b0@sun:~/tmp$ echo $i | sed -e 's/ /\\ /g' -e 's/pippo/paperino/g'
paperino\ pluto.txt


 possa ricavare piu' esattamente cosa vorresti fare...
Lo scopo di questo onliner č nobile: vuole essere uno onliner generico per
la sostituzione dei nomi di file. Una volta gestito il problema degli spazi
nei nomi dei files non resta che modificare la regexp finale e si puň fare
virtualmente qualsiasi cosa..


 paperino\ pluto.txt
Se quoti non devi piu' inserire gli escape. Prova il comando come te l'ho
scritto io.
$ ls -b
pippo\ paperino.txt
$ for i in *; do echo mv -i -- "$i" "`echo $i | sed 's/pippo/paperino/g'`";
done
mv -i -- pippo paperino.txt paperino paperino.txt
$ for i in pi*; do mv -i -- "$i" "`echo $i | sed 's/pippo/paperino/g'`";
done
$ ls -b 
paperino\ paperino.txt
(si', in questo caso con "echo mv ..." non si vede nulla di differente)

 (si', in questo caso con "echo mv ..." non si vede nulla di differente)
Funziona!!!
g4b0@sun:~/tmp$ ls
pippo\ pluto.txt
g4b0@sun:~/tmp$ for i in * ; do mv -i "$i" "`echo $i |
sed 's/pippo/paperino/g'`"; done
g4b0@sun:~/tmp$ ls
paperino\ pluto.txt
g4b0@sun:~/tmp$ echo mv -i "$i" "`echo $i | sed 's/pippo/paperino/g'`"
mv -i pippo pluto.txt paperino pluto.txt
Ma perchè l'echo non funziona? errore mio o bug?




In realta' l'echo funziona...solo che dall'output di echo non si capisce
quali e quanti argomenti sono stati passati ad echo. Esempio:
$ echo mv -i pippo pluto.txt paperino pluto.txt    # 6 argomenti
mv -i pippo pluto.txt paperino pluto.txt
$ echo mv -i "pippo pluto.txt" "paperino pluto.txt"  # 4 argomenti
mv -i pippo pluto.txt paperino pluto.txt
L'output e' lo stesso.

 ...
No, lo scopo non è affatto nobile; inventare l'acqua calda 
non è nobile, è solo inutile. In poche parole questo 
script rinomina gruppi di file alla maniera di come fanno
decine di script già esistenti (tra cui ren e rename, due 
tra i tanti). 
Sarebbe nobile provare a superare le limitazioni ed i bug 
di questi due ma prima effettua una ricerca sulla rete; è 
quasi sicuro che qualcun altro abbia fatto esattamente ciò 
che vuoi fare tu
man rename
man ren

 man ren
g4b0@slack:~$ ren
-bash: ren: command not found
Il rename fornito da slackware, come ho già specificato, non permette di
utilizzare le regexp, quindi i tool di cui parli risultano essere inutili
al mio scopo. Su debian, ad esempio, con rename avrei risolto molto in
fretta..
Non amo reinventare la ruota, ma ora che ho il mio ruotino lo userò ogni
volta in cui ne avrò bisogno. E lo potrà usara chiunque ne abbia bisogno,
dato che l'ho postato sul ng..


 Su debian, ad esempio, con rename avrei risolto molto in fretta..
È software libero!  Un semplice perl script, non è esclusiva di Debian,
basta cercarlo con zio Google (o copiarlo da una installazione Debian /
Ubuntu), hint: `/usr/bin/prename'.
http://tips.webdesign10.com/files/rename.pl.txt
-- 
 lupin®
------------------------------------------------------------------------
BULLONE: Plecipizio molto plofondo

 
http://tips.webdesign10.com/files/rename.pl.txt
Certo, ci sono mille modi per fare la stessa operazione. Il mio è stato un
ottimo esercizio di shell scripting, della quale ero un po' arrugginito..
In effetti avrei dovuto digitare 41 byte in meno per ottenere lo stesso
risultato, ma avrei dovuto sbattermi a cercare lo script ed installarlo :)
for i in * ; do mv -i "$i" "`echo $i |sed 's/pippo/paperino/g'`"; done
rename 's/pippo/paperino/g' *


 ...
Perche' ti complichi la vita? 
Esistono decine di script per rinominare gruppi di file,
ogni distribuzione ha il suo proprio script e, sia che 
venga chiamato rename, mmv, ren o piergiorgio, la tua 
distribuzione lo ha già installato e tu devi solo 
digitare ``man apropos''.

mallin.shetland wrote:

A parte il fatto che il mio oneliner non mi pare così complicato..
g4b0@slack:~$ apropos rename
Tcl_CommandTraceInfo (3)  - monitor renames and deletes of a command
Tcl_FSRenameFile [Tcl_FSRegister] (3)  - procedures to interact with any
filesystem
Tcl_TraceCommand [Tcl_CommandTraceInfo] (3)  - monitor renames and deletes
of a command
Tcl_UntraceCommand [Tcl_CommandTraceInfo] (3)  - monitor renames and deletes
of a command
hrename              (1)  - rename or move an HFS file or directory
ifrename             (8)  - rename network interfaces based on various
static criteria
ldapmodrdn           (1)  - LDAP rename entry tool
lvrename             (8)  - rename a logical volume
mmove                (1)  - move or rename an MSDOS file or subdirectory
mren                 (1)  - rename an existing MSDOS file
mv                   (1)  - move (rename) files
rename               (1)  - Rename files
rename               (2)  - change the name or location of a file
rename               (n)  - Rename or delete a command
renameat             (2)  - rename a file relative to directory file
descriptors
vgrename             (8)  - rename a volume group
XStoreName [XSetWMName] (3x)  - set or read a window's WM_NAME property
XStoreNamedColor [XStoreColors] (3x)  - set colors
Di utile salta fuori soltanto rename, che come ho già detto più volte, su
Slackware non supporta le regexp. 
