[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [riminilug-general] Risposta tardiva a: "Mi serve uno script"



Il 10/09/2012 13:16, Andrea Grossi ha scritto:
Ciao a tutti !!

Visto che sono stato "tirato" in ballo..

Da informazioni datemi da Andy Urbi sul tipo di file da
passare allo script , ne ho creato uno che avesse le seguenti
caratteristiche:
1) File di testo puro (non formattato tipo Open/Libre Office)

2) Il record iniziava con un nominativo racchiuso tra virgolette e,
    di seguito senza spazi, l'indirizzo e-mail racchiuso tra i
caratteri minore e maggiore (<  >  ); di seguito, senza spazi,
  vi era il carattere virgola (,) e uno spazio e poi si ricominciava col
record successivo.

3) Il file aveva la stessa "cadenza" ripetuta per ogni record.

Esempio: file.csv

"Tizio Tizi"<tiziotizi@xxxxxx>, "Caio Cai"<caiocai@xxxxxx>, "Sempronio
Semproni"<semproniosemproni@xxxxxx>,
"Mario Rossi"<mariorossi@xxxxxx>, "Guido Guidi"<guidoguidi@xxxxxx>,
"Cecco Cecchi"<ceccocecchi@xxxxxx>,

Volevo ottenere questo risultato:

Caio Cai            caiocai@xxxxxx
Cecco Cecchi        ceccocecchi@xxxxxx
Guido Guidi         guidoguidi@xxxxxx
Mario Rossi         mariorossi@xxxxxx
Sempronio Semproni  semproniosemproni@xxxxxx
Tizio Tizi          tiziotizi@xxxxxx

Ho aperto un terminale ( Scorciatoia da tastiera CTRL + ALT + T )
e , avendo il file.csv, ho digitato:

cat file.csv |awk 'BEGIN {RS=", "}{print $0}'|sed -e '/^$/d'>  nuovo.csv

in awk
-ho impostato la variabile RS (Record Separator) con virgola spazio (, )
-print $0 stampa l'intero record

in sed
- ho eliminato le righe vuote e ho salvato il tutto in un nuovo file
(nuovo.csv)

Eccolo:

"Tizio Tizi"<tiziotizi@xxxxxx>
"Caio Cai"<caiocai@xxxxxx>
"Sempronio Semproni"<semproniosemproni@xxxxxx>
"Mario Rossi"<mariorossi@xxxxxx>
"Guido Guidi"<guidoguidi@xxxxxx>
"Cecco Cecchi"<ceccocecchi@xxxxxx>

Poi sempre nel terminale ho digitato:

cat nuovo.csv |sed 's|"<|,|g;s|"||g;s|>||g'>nuovo2.csv

in sed
- ho sostituito la sequenza "<  con il carattere virgola (,)
- di seguito ho eliminato le virgolette (") e il carattere>
- è stato creato il file nuovo2.csv (qui di seguito riportato)

Tizio Tizi,tiziotizi@xxxxxx
Caio Cai,caiocai@xxxxxx
Sempronio Semproni,semproniosemproni@xxxxxx
Mario Rossi,mariorossi@xxxxxx
Guido Guidi,guidoguidi@xxxxxx
Cecco Cecchi,ceccocecchi@xxxxxx

Infine ho digitato :

cat nuovo2.csv |column -t -s , |sort>  file_finale.csv

in column
- la -t indica che viene applicato un formato tabella al file
- la -s indica che il carattere , (virgola) viene utilizzato come
separatore dei campi del record e li presenta incolonnati.

sort ordina alfabeticamente (a ->  z)
viene creato il file_finale.csv

Output:

Caio Cai            caiocai@xxxxxx
Cecco Cecchi        ceccocecchi@xxxxxx
Guido Guidi         guidoguidi@xxxxxx
Mario Rossi         mariorossi@xxxxxx
Sempronio Semproni  semproniosemproni@xxxxxx
Tizio Tizi          tiziotizi@xxxxxx

N.B. Non sono un informatico e ho impiegato diverso tempo per venirne a
capo :)
Sicuramente vi sono metodi più eleganti e raffinati per ottenere la
stessa cosa.

Anzi chi avesse soluzioni alternative, si faccia avanti !

Vi saluto !

Andrea G.



E bravo Andrea! Allora non sei timido :D

Intanto grazie per la piegazione e complimenti per il risultato portato a casa. Come dici bene, lo stesso risultato si può raggiungere in tanti modi e con strumenti diversi, ma intanto questo sembra funzionare.

Visto che siamo tutti qui per imparare e migliorare, ho solo un paio di note alla tua spiegazione:

premesso che anch'io conosco molto poco sed e ogni volta che lo devo usare mi fa arrabbiare, volevo chiedere a te e ad altri che differenza c'è tra il passare lo script di sed con il parametro -e (primo comando) e senza (secondo comando).

leggendo questo nella man page:
----
If  no  -e, --expression, -f, or --file option is given, then the first
non-option argument is taken as  the  sed  script  to  interpret.   All
remaining  arguments  are  names  of input files; if no input files are
specified, then the standard input is read.
-----------
sembra che la chiamata senza -e sia il modo implicito per passare lo script, e quindi, in assenza di altri parametri, le 2 modalità sono esattamente equivalenti (giusto?). Mi faceva solo strano vedere che in un posto lo usi e nell'altro no.... o c'è una spiegazione diversa e più fine?

poi, il comando :
	cat nuovo.csv |sed 's|"<|,|g;s|"||g;s|>||g'>nuovo2.csv

mi suona un po' strano perchè solitamente (anche da man page) il carattere usato nel comando di sostituzione è / e non |:
	sed 's/"</,/g;s/"//g;s/>//g'
qualcuno sa darmi una spiegazione del perchè funzioni ugualmente e quindi perchè i 2 caratteri siano equivalenti?

Infine, ma è una sciocchezza, invece di usare cat e redirigere via pipe a sed, si può passare direttamente il nome del file a sed:

	sed 's/"</,/g;s/"//g;s/>//g' nuovo.csv > nuovo2.csv


Visto che poi Andrea chiedeva metodi alternativi, invece di usare awk si può usare sempre sed per fare lo split del file:
	sed 's/, /\n/g' file.csv
Ovvero si sostituisce il la coppia di caratteri virgola-spazio (, ) con il carattere di newline.... ma non aggiunge molto a quanto fatto da Andrea via awk :)
	

Ivan


---------------------------------------------------------------------
Per cancellarsi, scrivi a: riminilug-general-unsubscribe@xxxxxxxxxxxx
Se vuoi conoscere altri comandi, scrivi a: riminilug-general-help@xxxxxxxxxxxx