Newsgroup: it.comp.lang.perl
Titolo: Aiutino per parsare un file

Problema:
ho un file identico a questo (senza conoscere il contenuto di ID:)
############################
Cryptoki version 2.20
Manufacturer     bit4id srl
Library          bit4id PKCS#11 (ver 1.1)
Available slots:
Slot 0           ACS ACR38U 00 00
   token label:   CNS
   token manuf:   ST Incard
   token model:   CNS
   token flags:   rng, login required, PIN initialized, token initialized
   serial num  :  7420093805656
Certificate Object, type = X.509 cert
   label:      CNS User Certificate
   ID:         434e5377
Data object 1002
   label:          'PDATA'
   application:    'PDATA'
   app_id:         141365656
   flags:           modifiable
Public Key Object; RSA 1024 bits
   label:      CNS User Public Key
   ID:         434e5377
   Usage:      encrypt, verify
Certificate Object, type = X.509 cert
   label:      DS User Certificate0
   ID:         445777
Public Key Object; RSA 1024 bits
   label:      DS User Public Key0
   ID:         445777
   Usage:      encrypt, verify
#######################
dovrei recuperare il valore dell'ultimo ID: (445777) che ï¿œ la variabile 
che mi interessa ma sono un p'ï¿œ arrugginito in Perl ultimamente..

 dovrei recuperare il valore dell'ultimo ID: (445777) 
In maniera spaghettosa, come mi compete, direi una cosa cosï¿œ:
use warnings;
use strict;
open my $fh, $ARGV[0] or die "$!";
my $tutto = do { local $/; <$fh> };
my @ID = $tutto =~ /ID\:\s+([^\n]+)/g;
print "$ID[-1]\n";

Premetto che non sono un programmatore perl (lo uso solo per risolvere 
problemi) quindi mi associo alla spaghetteria.
Detto cio', ammettendo che il tuo file si chiami "pippo.txt", nella 
variabile "$last_id" avrai il valore che ti serve:
--------------------------------------
open(XFILE, "pippo.txt");
@buffer = <XFILE>;
close(XFILE);
$buffer[$#buffer-1] =~ s/[^0-9]//g;
my $last_id = $buffer[$#buffer-1]; 
--------------------------------------
PS: visto che da shell ottengo quello che voglio con il comando:
# grep 'ID: ' pippo.txt | tail -n1 | awk '{print $NF}'
personalmente in perl farei cosi':  
--------------------------------------
my $last_id=`grep 'ID: ' pippo.txt | tail -n1 | awk '{print \$NF}'`;
chomp $last_id;
--------------------------------------
...sempre restando in spaghetteria ;-)

 my $tutto = do { local $/; <$fh> };
Userei la versione a tre argomenti per la open per questioni generali
di abitudine "sicura", anche se in questo caso la eviterei
direttamente:
# senza open prima...
my $tutto = do { local $/; <> };
In questo modo, volendo, puoi anche utilizzarlo come filtro in una
pipe di comandi.
Per il resto... non mi sembra spaghettoso per niente!
Ciao,
   Flavio.

 # grep 'ID: ' pippo.txt | tail -n1 | awk '{print $NF}'
Mi c'aggancio, facendo vedere come da shell avremmo potuto farlo anche 
con (il solo) perl:
perl -ne '/ID:\s*(.+)$/ and $id=$1; END{print "$id\n"}' pippo.txt
con qualche guadagno velocistico.
P.S.
Con perl 5.10, il one-liner di cui sopra si può scrivere con qualche 
carattere in meno:
perl -nE '/ID:\s*(.+)$/ and $id=$1; END{say $id}' pippo.txt

 con qualche guadagno velocistico.
# perl -ne '/ID:\s*(.+)$/ and $id=$1; END{print "$id\n"}' pippo.txt
-- intorno ai 008s
# grep 'ID: ' pippo.txt | tail -n1 | awk '{print $NF}'
-- intorno ai 020s
Questo mi piace (anche se si scontra con vecchie "shell'abitudini").
Grazie per la dritta, registro e pago il prossimo giro di carbonara.

 # grep 'ID: ' pippo.txt | tail -n1 | awk '{print $NF}'
Non l'ho detto, ma questa invece m'era piaciuta.
Quella della penultima riga no, ma questa sì ;-)

Andrea Maestrutti ha scritto:

Ringrazio tutti per le RE: ottimo lavoro

 my $last_id = $buffer[$#buffer-1];
Ma chi l'ha scritta questa porcata? Il sed e' sbagliato.
Se l'ID selezionato contiene delle lettere es: "ID:         434e5377" 
lo script restituisce "4345377".
Se non si e' in grado di fare le cose almeno non postatele
...che gente!!! ;-)