Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

problema tr///

1 view
Skip to first unread message

steoware

unread,
Jun 19, 2008, 3:55:53 AM6/19/08
to
Salve,
ho un problema con la funzione tr///.

Dovrei modificare dei nomi dei file nelle ultime 2 cifre che precedono il
primo punto. Ad esempio:

Old Filename: fosP8E4#fosP8E4h01.b1.ab1
New Filename: fosP8E4#fosP8E4h07.b1.ab1

In particolare le cifre da 01 a 06 devono diventare da 07 a 12.

A tal fine ho scritto :
[..]
substr(@fileNameUpToDot[0], -2, 2) =~
tr/(01)(02)(03)(04)(05)(06)/(07)(08)(09)(10)(11)(12)/;
[...]

che a quanto pare funziona per 01, 02, 03 ma non con le cifre successive,
per cui ottengo:

ESATTI
Old Filename: fosP8E4#fosP8E4h01.b1.ab1 New Filename:
fosP8E4#fosP8E4h07.b1.ab1
Old Filename: fosP8E4#fosP8E4h02.b1.ab1 New Filename:
fosP8E4#fosP8E4h08.b1.ab1
Old Filename: fosP8E4#fosP8E4h03.b1.ab1 New Filename:
fosP8E4#fosP8E4h09.b1.ab1

ERRATI
Old Filename: fosP8E4#fosP8E4h04.b1.ab1 New Filename:
fosP8E4#fosP8E4h00.b1.ab1
Old Filename: fosP8E4#fosP8E4h05.b1.ab1 New Filename:
fosP8E4#fosP8E4h01.b1.ab1
Old Filename: fosP8E4#fosP8E4h06.b1.ab1 New Filename:
fosP8E4#fosP8E4h02.b1.ab1

non risco a darmi spiegazioni del perchč...

Idee ed alternative sono ben accette!
ciao
Stefano

--

questo articolo e` stato inviato via web dal servizio gratuito
http://www.newsland.it/news segnala gli abusi ad ab...@newsland.it


Giovanni Zezza

unread,
Jun 19, 2008, 4:55:10 AM6/19/08
to
steoware, nel messaggio <g3d3e9$jvi$1...@news.newsland.it>, scriveva:

>ho un problema con la funzione tr///.
>
>Dovrei modificare dei nomi dei file nelle ultime 2 cifre che precedono il
>primo punto. Ad esempio:
>
>Old Filename: fosP8E4#fosP8E4h01.b1.ab1
>New Filename: fosP8E4#fosP8E4h07.b1.ab1
>
>In particolare le cifre da 01 a 06 devono diventare da 07 a 12.
>
>A tal fine ho scritto :
>[..]
>substr(@fileNameUpToDot[0], -2, 2) =~
>tr/(01)(02)(03)(04)(05)(06)/(07)(08)(09)(10)(11)(12)/;
>...

>non risco a darmi spiegazioni del perchè...

Perché, che tu ci creda o no, l'espressione:

tr/(01)(02)(03)(04)(05)(06)/(07)(08)(09)(10)(11)(12)/;

è equivalente a:

tr/0123456()/0789012()/;

L'operatore tr/// opera sui singoli caratteri. Punto. Ogni singolo
carattere nell'elenco di ricerca viene rimpiazzato da ogni singolo
carattere corrispondente nell'elenco ldi sostituzione. Le parentesi
nell'elenco di ricerca o in quello di sostituzione rappresentano solo sé
stesse, e NON indicano un raggruppamento.

>Idee ed alternative sono ben accette!

Devi usare l'operatore s///, se vuoi utilizzare le espressioni regolari, o
costruirti una procedura di sostituzione ad hoc.

Ciao.

antani

unread,
Jun 19, 2008, 4:56:29 AM6/19/08
to
On Thursday 19 June 2008 09:55, steoware wrote:

> Salve,
> ho un problema con la funzione tr///.
>
> Dovrei modificare dei nomi dei file nelle ultime 2 cifre che precedono il
> primo punto. Ad esempio:
>
> Old Filename: fosP8E4#fosP8E4h01.b1.ab1
> New Filename: fosP8E4#fosP8E4h07.b1.ab1
>
> In particolare le cifre da 01 a 06 devono diventare da 07 a 12.
>
> A tal fine ho scritto :
> [..]
> substr(@fileNameUpToDot[0], -2, 2) =~
> tr/(01)(02)(03)(04)(05)(06)/(07)(08)(09)(10)(11)(12)/;
> [...]

Puoi fare questo:

s/(\d\d)(?=.{7}$)/sprintf "%02d",$1+6/e;

direttamente sulla stringa che contiene l'intero nome.

Questa e' un'idea, ovviamente puoi cambiare la parte nel lookahead in modo
che $1 nel RHS identifichi esattamente le due cifre che vuoi cambiare.

steoware

unread,
Jun 19, 2008, 5:37:41 AM6/19/08
to
antani ha scritto:

> Puoi fare questo:
> s/(dd)(?=.{7}$)/sprintf "%02d",$1+6/e;

grazie mille, ma...me lo potresti spiegare?

e poi...in tal caso, 04+6 mi da 10 o 010 ?

antani

unread,
Jun 19, 2008, 5:54:00 AM6/19/08
to
On Thursday 19 June 2008 11:37, steoware wrote:

> antani ha scritto:
>
>> Puoi fare questo:
>> s/(dd)(?=.{7}$)/sprintf "%02d",$1+6/e;
>
> grazie mille, ma...me lo potresti spiegare?

Bisogna individuare le due cifre che interessano nella parte sinistra della
sostituzione (\d\d, anche se per qualche motivo i backslash sono andati
persi nella risposta). Per essere sicuri che quelle siano proprio le due
cifre che bisogna modificare, un lookahead controlla che dopo quelle due
cifre ci siano esattamente 7 caratteri e poi la fine della stringa. Le
parentesi attorno al \d\d servono per avere disponibile nella parte destra
la variabile $1 contenente cio' che effettivamente e' stato matchato (ossia
le famose due cifre).

Lo switch /e dice a Perl di valutare l'espressione che sta nella parte
destra e poi usare il risultato della valutazione come stringa per la
sostituzione.

> e poi...in tal caso, 04+6 mi da 10 o 010 ?

Non importa, perche' la sprintf produce comunque il risultato giusto,
ossia %02d (2 cifre con eventuale 0 iniziale). Se invece non si usa la
sprintf, il risultato potrebbe non essere quello voluto:

$ echo 'fosP8E4#fosP8E4h01.b1.ab1' | perl -pe 's/(\d\d)(?=.{7}$)/$1+6/e;'
fosP8E4#fosP8E4h7.b1.ab1

Questo non va bene perche' nella valutazione di 01+6 Perl trasforma il tutto
in un numero, e quindi toglie gli zeri non significativi. Con la sprintf si
forza la ri-trasformazione in stringa col formato voluto.

Ciao!

steoware

unread,
Jun 19, 2008, 6:44:26 AM6/19/08
to
antani ha scritto:

> Bisogna individuare le due cifre che interessano nella parte sinistra della

> sostituzione (dd, anche se per qualche motivo i backslash sono andati
> persi nella risposta).

ok...il problema č che non sempre la regola dei 7 caratteri č rispettata.
Per questo ho usato:

[...]
my @fileNameUpToDot = split (/./, $file);


substr(@fileNameUpToDot[0], -2, 2)

che mi intercetta gli ultimi 2 caratteri prima del primo punto.

come modifico questa variabile cosě ottenuta con i tuoi suggerimenti?

ho usato: substr(@fileNameUpToDot[0], -2, 2) =~ s/$1/sprintf "%02d",$1+6/;
ma ottengo:
New Filename: fosP8E4#fosP8E4hsprintf "%02d",+606.g1.ab1

antani

unread,
Jun 19, 2008, 6:58:18 AM6/19/08
to
On Thursday 19 June 2008 12:44, steoware wrote:

> ok...il problema è che non sempre la regola dei 7 caratteri è rispettata.


> Per questo ho usato:
>
> [...]
> my @fileNameUpToDot = split (/./, $file);
> substr(@fileNameUpToDot[0], -2, 2)
>
> che mi intercetta gli ultimi 2 caratteri prima del primo punto.
>

> come modifico questa variabile così ottenuta con i tuoi suggerimenti?


>
> ho usato: substr(@fileNameUpToDot[0], -2, 2) =~ s/$1/sprintf "%02d",$1+6/;
> ma ottengo:
> New Filename: fosP8E4#fosP8E4hsprintf "%02d",+606.g1.ab1

Il $1 si usa nella parte destra della sostituzione, non a sinistra, e
inoltre devi usare lo switch /e.

Se la condizione e' "i due caratteri (cifre) che precedono il primo punto
nella stringa", allora usa questo, anche senza lookahead:

...
my $file='fosP8E4#fosP8E4h01.b1.ab1';
$file =~ s/([^.]+)(\d\d)/sprintf "%s%02d",$1,$2+6/e;
print "New Filename: $file\n";

Sostanzialmente, prende la piu' lunga stringa possibile che non contiene
punti, seguita da due cifre. Se il formato e' quello che hai descritto,
dovrebbe proprio prendere le due cifre che ti interessano.

antani

unread,
Jun 19, 2008, 7:11:37 AM6/19/08
to
On Thursday 19 June 2008 12:44, steoware wrote:

> antani ha scritto:
>
>> Bisogna individuare le due cifre che interessano nella parte sinistra
>> della sostituzione (dd, anche se per qualche motivo i backslash sono
>> andati persi nella risposta).
>

> ok...il problema è che non sempre la regola dei 7 caratteri è rispettata.


> Per questo ho usato:
>
> [...]
> my @fileNameUpToDot = split (/./, $file);
> substr(@fileNameUpToDot[0], -2, 2)
>
> che mi intercetta gli ultimi 2 caratteri prima del primo punto.
>

> come modifico questa variabile così ottenuta con i tuoi suggerimenti?

Puoi anche non usare espressioni regolari:

my @fileNameUpToDot = split (/\./, $file);
substr($fileNameUpToDot[0],-2,2,
sprintf "%02d",substr($fileNameUpToDot[0], -2, 2)+6);
$file=join ".",@fileNameUpToDot;

steoware

unread,
Jun 19, 2008, 8:54:46 AM6/19/08
to
antani ha scritto:


> Puoi anche non usare espressioni regolari:

> my @fileNameUpToDot = split (/./, $file);


> substr($fileNameUpToDot[0],-2,2,
> sprintf "%02d",substr($fileNameUpToDot[0], -2, 2)+6);
> $file=join ".",@fileNameUpToDot;

> print "New Filename: $filen";

perfetto...questa soluzione è quella più vicina a cosa avevo in mente!!

grazie infinite.
S.

0 new messages