[Risolto] Un tipo di conteggio

Linguaggi di programmazione: php, perl, python, C, bash, ecc.

[Risolto] Un tipo di conteggio

Messaggioda eb-ash » sabato 6 luglio 2019, 14:18

Avrei bisogno di un aiutino, non so come si possa esprimere a parola e quindi scusate il titolo molto generico.

Ho un file di testo che contiene:

A: 1
A (a): 2
B: 3
B (a): 2
B (b): 2
B (c): 1

Vorrei ottenere l'output:

A (a) : 3

B (a) (b) (c) : 8
Ultima modifica di eb-ash il martedì 30 luglio 2019, 2:25, modificato 2 volte in totale.
si è vero uso un mac. Ma detesto i maccisti del web. Se la tirano, non ti aiutano, sono abituati ad avere la pappa fatta e non costruirsi le cose, e sono troppo pochi... quando serve non ci sono mai. Voglio imparare un po' di Bash per fare tante cose utili perchè questo sono qua... senza formazione specifica ma in fondo è unix che permette di fare le cose a pezzetti, no?
Avatar utente
eb-ash
Prode Principiante
 
Messaggi: 117
Iscrizione: febbraio 2019
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda UbuNuovo » martedì 9 luglio 2019, 15:43

Mi ero dimenticato di questo post, ora ho scritto il codice, ho usato AWK.
Come sei messo con AWK?
Vuoi un imboccata o il codice finito?

Prima prova da solo, poi semmai chiedi.
Come al solito ti consiglio di fare le prove su una struttura di dati semplice, come quella del tuo esempio.
il file 'dati.txt' contiene:
Codice: Seleziona tutto
A: 1
A (a): 2
B: 3
B (a): 2
B (b): 2
B (c): 1

Per prima cosa ti conviene individuare con sicurezza in quali campi sono distribuiti i dati:
Codice: Seleziona tutto
8-) awk -F'[ :]' '{print "$1",$1,"$2",$2,"$3",$3,"$4",$4}' dati.txt
$1 A $2  $3 1 $4
$1 A $2 (a) $3  $4 2
$1 B $2  $3 3 $4
$1 B $2 (a) $3  $4 2
$1 B $2 (b) $3  $4 2
$1 B $2 (c) $3  $4 1


Come vedi i valori da sommare sono presenti in "$3" o in "$4", questo dipende dalla presenza o meno dei valori in "$2"
Quindi devi usare il costrutto "if, else" per distinguere i due casi e assegnare i valori.
I valori numerici puoi assegnarli ad un array e sommarli direttamente, utilizzando l'operatore '+='
Codice: Seleziona tutto
array[indice]+=valore
i valori finali li stamperai ciclando l'array in END.
Per immagazzinare le stringhe (a), (b), (c); ho usato un'altro array con lo stesso indice del precedente, dove concateno il vecchio contenuto con il nuovo (contenuto in $2) in modo da poterne stampare il contenuto finale, dallo stesso ciclo del primo array.

Spero di essere stato comprensibile.
Nel caso in cui sia il primo a rispondere ad una richiesta di aiuto...chiunque abbia una soluzione migliore o anche solo diversa dalla mia è incoraggiato ad intervenire liberamente senza inviarmi alcun messaggio privato. In programmazione è basilare sapere che si può ottenere il medesimo risultato utilizzando metodi diversi.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 3490
Iscrizione: dicembre 2009
Desktop: Mate
Distribuzione: Ubuntu 14.04
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda eb-ash » giovedì 11 luglio 2019, 14:22

UbuNuovo Immagine ha scritto:Come sei messo con AWK?
Vuoi un imboccata o il codice finito?


Non mi oso... mi hai aiutato tanto finora :shy:

UbuNuovo Immagine ha scritto:Per prima cosa ti conviene individuare con sicurezza in quali campi sono distribuiti i dat.





Questa è la prima difficoltà che sto incontrando perchè nella realtà al posto di "A", "B" etc. ci sono nomi con varie parole... si tratta sempre di artisti che hanno inciso sotto pseudonimi quindi c'è di tutto....


Cmq cerco di studiare come affrontare il problema. Se non ci sono nuove da parte tua credo che mi farò sentire tra un migliaio di anni.... :verysad:
si è vero uso un mac. Ma detesto i maccisti del web. Se la tirano, non ti aiutano, sono abituati ad avere la pappa fatta e non costruirsi le cose, e sono troppo pochi... quando serve non ci sono mai. Voglio imparare un po' di Bash per fare tante cose utili perchè questo sono qua... senza formazione specifica ma in fondo è unix che permette di fare le cose a pezzetti, no?
Avatar utente
eb-ash
Prode Principiante
 
Messaggi: 117
Iscrizione: febbraio 2019
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda UbuNuovo » giovedì 11 luglio 2019, 15:24

Me lo immaginavo! Naturalmente i nomi possono essere di una due o più parole.
Devi fare in modo di avere dei separatori decenti trai vari campi, altrimenti per un programma è impossibile distinguere dove comincia un campo e ne finisce un altro.

Quando avrai i dati con la sintassi giusta puoi usare un metodo tipo questo:
Codice: Seleziona tutto
awk -F'[ :]' '{if($4==""){arr[$1]+=$3}else{arr[$1]+=$4;arrp[$1]=arrp[$1]" "$2;}} END {for (var in arr) print var arrp[var]" : " arr[var]}' dati.txt

provo:
Codice: Seleziona tutto
8-) awk -F'[ :]' '{if($4==""){arr[$1]+=$3}else{arr[$1]+=$4;arrp[$1]=arrp[$1]" "$2;}} END {for (var in arr) print var arrp[var]" : " arr[var]}' dati.txt
A (a) : 3
B (a) (b) (c) : 8
8-)
Nel caso in cui sia il primo a rispondere ad una richiesta di aiuto...chiunque abbia una soluzione migliore o anche solo diversa dalla mia è incoraggiato ad intervenire liberamente senza inviarmi alcun messaggio privato. In programmazione è basilare sapere che si può ottenere il medesimo risultato utilizzando metodi diversi.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 3490
Iscrizione: dicembre 2009
Desktop: Mate
Distribuzione: Ubuntu 14.04
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda eb-ash » sabato 13 luglio 2019, 12:55

Codice: Seleziona tutto
a=$(sed -e "s/ /∑/g" -e "s/:∑/: /g" -e "s/∑(/ (/g" DATI.txt)

echo $a| awk -F'[ :]' '{if($4==""){arr[$1]+=$3}else{arr[$1]+=$4;arrp[$1]=arrp[$1]" "$2;}} END {for (var in arr) print var arrp[var]" : " arr[var]}' DATI2.txt |sed -e "s/∑/ /g"


Va molto bene! Riesco a mettere ogni genere di parole sostituendo gli spazi vuoti con un carattere sentinella. Mi piacerebbe evitare il salvataggio su file, il "DATI2.txt" con un'altra variabile ma non so come fare
si è vero uso un mac. Ma detesto i maccisti del web. Se la tirano, non ti aiutano, sono abituati ad avere la pappa fatta e non costruirsi le cose, e sono troppo pochi... quando serve non ci sono mai. Voglio imparare un po' di Bash per fare tante cose utili perchè questo sono qua... senza formazione specifica ma in fondo è unix che permette di fare le cose a pezzetti, no?
Avatar utente
eb-ash
Prode Principiante
 
Messaggi: 117
Iscrizione: febbraio 2019
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda UbuNuovo » sabato 13 luglio 2019, 16:35

Sempre allo stesso modo: $(...)
Codice: Seleziona tutto
risultati=$(awk -F'[ :]' '{if($4==""){arr[$1]+=$3}else{arr[$1]+=$4;arrp[$1]=arrp[$1]" "$2;}} END {for (var in arr) print var arrp[var]" : " arr[var]}' <<< "$a" | sed -e 's/∑/ /g')


Però, invece di aggiungere e togliere separatori continuamente, ti conviene ottenere un file che ti faccia da database, che abbia tutti i separatori, poi solo da ultimo, per il risultato finale, sostituisci i separatori che non vuoi.

Quando ti arriva un nuovo file lo aggiungi al file database e poi lavori solo su quello.
Nel caso in cui sia il primo a rispondere ad una richiesta di aiuto...chiunque abbia una soluzione migliore o anche solo diversa dalla mia è incoraggiato ad intervenire liberamente senza inviarmi alcun messaggio privato. In programmazione è basilare sapere che si può ottenere il medesimo risultato utilizzando metodi diversi.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 3490
Iscrizione: dicembre 2009
Desktop: Mate
Distribuzione: Ubuntu 14.04
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda eb-ash » sabato 27 luglio 2019, 0:41

Devo dire che ho trovato un problema. Questo awk
Codice: Seleziona tutto
 risultati=$(awk -F'[ :]' '{if($4==""){arr[$1]+=$3}else{arr[$1]+=$4;arrp[$1]=arrp[$1]" "$2;}} END {for (var in arr) print var arrp[var]" : " arr[var]}' <<< "$a" | sed -e 's/∑/ /g')

mi risulta incompatibile con questo
Codice: Seleziona tutto
awk -F";" '{a[$1]+=$NF} END {for(i in a)print i": "a[i];}' < <(sed -e 's/   /;/' -e 's@\([0-9]\+\) \(.*\)@\2;\1@'


In pratica funziona solo il primo che antepongo e ottengo un ouput con i risultati buoni del primo ma con la mancanza di risultati del secondo.

Forse si può fare la stessa cosa senza awk?
si è vero uso un mac. Ma detesto i maccisti del web. Se la tirano, non ti aiutano, sono abituati ad avere la pappa fatta e non costruirsi le cose, e sono troppo pochi... quando serve non ci sono mai. Voglio imparare un po' di Bash per fare tante cose utili perchè questo sono qua... senza formazione specifica ma in fondo è unix che permette di fare le cose a pezzetti, no?
Avatar utente
eb-ash
Prode Principiante
 
Messaggi: 117
Iscrizione: febbraio 2019
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda UbuNuovo » sabato 27 luglio 2019, 13:38

:? ???
Non sono un indovino.
Nel caso in cui sia il primo a rispondere ad una richiesta di aiuto...chiunque abbia una soluzione migliore o anche solo diversa dalla mia è incoraggiato ad intervenire liberamente senza inviarmi alcun messaggio privato. In programmazione è basilare sapere che si può ottenere il medesimo risultato utilizzando metodi diversi.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 3490
Iscrizione: dicembre 2009
Desktop: Mate
Distribuzione: Ubuntu 14.04
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda eb-ash » domenica 28 luglio 2019, 0:12

Ok, non era chiaro...

Volevo dire, se secondo te il tuo awk si può integrare con il mio. MIo... si fa per dire, quello che mi avevi preparato è che è il motore di tutto lo script. Secondo te è fattibile?

Sto provando a mescolarli nel pentolone... ti farò sapere se ci riuscirò...
si è vero uso un mac. Ma detesto i maccisti del web. Se la tirano, non ti aiutano, sono abituati ad avere la pappa fatta e non costruirsi le cose, e sono troppo pochi... quando serve non ci sono mai. Voglio imparare un po' di Bash per fare tante cose utili perchè questo sono qua... senza formazione specifica ma in fondo è unix che permette di fare le cose a pezzetti, no?
Avatar utente
eb-ash
Prode Principiante
 
Messaggi: 117
Iscrizione: febbraio 2019
Sesso: Maschile

Re: Un tipo di conteggio

Messaggioda eb-ash » domenica 28 luglio 2019, 9:36

Ho capito cosa mi serve, Ubu! Niente pentolone... mi serve solo escludere da un'awk le righe con una certa parola chiave e dall'altro awk le righe senza quella parola. Poi unire i due risultati. Forse riesco a farcela da solo...
eh la notte porta consiglio... hi hi..
si è vero uso un mac. Ma detesto i maccisti del web. Se la tirano, non ti aiutano, sono abituati ad avere la pappa fatta e non costruirsi le cose, e sono troppo pochi... quando serve non ci sono mai. Voglio imparare un po' di Bash per fare tante cose utili perchè questo sono qua... senza formazione specifica ma in fondo è unix che permette di fare le cose a pezzetti, no?
Avatar utente
eb-ash
Prode Principiante
 
Messaggi: 117
Iscrizione: febbraio 2019
Sesso: Maschile

Re: (Risolto) Un tipo di conteggio

Messaggioda eb-ash » lunedì 29 luglio 2019, 21:30

:woot: :woot: :woot: :woot: :woot:

Funziona perfettamente

era già perfetto, ho fatto un po' di pasticci io con i caratteri delimitatori. Mancanza di metodo.
Mi è molto servito questo schema per capire cosa sbagliavo
Codice: Seleziona tutto
 awk -F'[ :]' '{print "$1",$1,"$2",$2,"$3",$3,"$4",$4}'


Adesso filtra meravigliosamente un sacco di nomi complicati, senza che io debba modificare le mie abitudini nominatoriei!
L'unica cosa che ho dovuto fare e inserire prima
Codice: Seleziona tutto
 -e 's/;.*;/;/'

in modo da eliminare i tanti delimitatori dovuti alla miriade di casi particolari nei nomi dei miei file.

Non me lo permettono ma metterei cento faccine. Grazie, Ubu!
si è vero uso un mac. Ma detesto i maccisti del web. Se la tirano, non ti aiutano, sono abituati ad avere la pappa fatta e non costruirsi le cose, e sono troppo pochi... quando serve non ci sono mai. Voglio imparare un po' di Bash per fare tante cose utili perchè questo sono qua... senza formazione specifica ma in fondo è unix che permette di fare le cose a pezzetti, no?
Avatar utente
eb-ash
Prode Principiante
 
Messaggi: 117
Iscrizione: febbraio 2019
Sesso: Maschile

Re: (Risolto) Un tipo di conteggio

Messaggioda UbuNuovo » lunedì 29 luglio 2019, 22:04

Bene! Sei sulla buona strada. Meno separatori ci sono e più è facile gestire i dati. :birra:

Quando chiedi supporto ricordati di fornire sempre più informazioni possibili su ciò che hai e su quello che vuoi ottenere (input, codice, output ottenuto, output desiderato).
Te sai sempre di cosa parli, chi cerca di aiutarti no.

"Risolto" mettilo tra parentesi quadrate, è una convenzione, utile per le ricerche.
Ciaux
Nel caso in cui sia il primo a rispondere ad una richiesta di aiuto...chiunque abbia una soluzione migliore o anche solo diversa dalla mia è incoraggiato ad intervenire liberamente senza inviarmi alcun messaggio privato. In programmazione è basilare sapere che si può ottenere il medesimo risultato utilizzando metodi diversi.
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 3490
Iscrizione: dicembre 2009
Desktop: Mate
Distribuzione: Ubuntu 14.04
Sesso: Maschile


Torna a Programmazione

Chi c’è in linea

Visualizzano questa sezione: 0 utenti registrati e 6 ospiti